面向对象:
就是把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。对同类对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。程序流程由用户在使用中决定。对象即为人对各种具体物体抽象后的一个概念,人们每天都要接触各种各样的对象,如手机就是一个对象。
面向对象编程(OOP: object-oriented programming)
面向对象与面向过程的区别
项目名称 | 面向对象程序设计 | 面向过程程序设计(也叫结构化编程) |
定义 | 面向对象顾名思义就是把现实中的事务都抽象成为程序设计中的“对象”,其基本思想是一切皆对象,是一种“自下而上”的设计语言,先设计组件,再完成拼装。 | 面向对象顾名思义就是把现实中的事务都抽象成为程序设计中的“对象”,其基本思想是一切皆对象,是一种“自下而上”的设计语言,先设计组件,再完成拼装。 |
特点 | 封装、继承、多态 | 算法+数据结构 |
优势 | 适用于大型复杂系统,方便复用、 | 适用于简单系统,容易理解 |
劣势 | 比较抽象、性能比面向过程低 | 难以应对复杂系统,难以复用,不易维护、不易扩展 |
对比 | 易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护 | 性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。 |
设计语言 | Java、Smalltalk、EIFFEL、C++、Objective-、C#、Python等 | C、Fortran |
1、面向对象三大主要特征
封装、继承、多态
①封装
两层含义:
一层含义是把对象的属性和行为看成一个密不可分的整体,将这两者“封装”在一个不可分割的独立单元(即对象)中;另一层含义指“信息隐藏”,把不需要让外界知道的信息隐藏起来,有些对象的属性及行为允许外界用户知道或使用,但不允许更改,而另一些属性或行为,则不允许外界知晓,或只允许使用对象的功能,而尽可能隐藏对象的功能实现细节。
封装的优点
良好的封装能够减少耦合,符合程序设计追求“高内聚,低耦合”。
类内部的结构可以自由修改。
可以对成员变量进行更精确的控制。
隐藏信息实现细节。
②继承
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承的好处:
(1)提高类代码的复用性
(2)提高了代码的维护性
(3)使得类和类产生了关系,是多态的前提(它也是继承的一个弊端,类的耦合性提高了)
继承的特性:
子类拥有父类非 private 的属性、方法。
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法,即重写父类方法。
Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
function Animal(nick, age) {
this.nick = nick;
this.age = age;
}
Animal.prototype.skill = function() {
console.log('觅食')
}
function Dog(nick, age, type) {
// this.nick = nick;
// this.age = age;
Animal.call(this, nick, age);
Animal.apply(this, [nick, age]);
this.type = type;
}
// 我们使用call和apply方式实现构造函数的继承
// call与apply作用:改变this指向
// 浅拷贝,不能这么写,容易对父级的原型进行修改
// Dog.prototype = Animal.prototype;
// 推荐使用就for in
for (var x in Animal.prototype) {
Dog.prototype[x] = Animal.prototype[x]
}
Dog.prototype.jump = function() {
console.log("jump");
}
var d = new Dog('dd', 6, '柯基');
d.skill();
③多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态的优点
- 1. 消除类型之间的耦合关系
- 2. 可替换性
- 3. 可扩充性
- 4. 接口性
- 5. 灵活性
- 6. 简化性
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象
比如:Parent p = new Child();
2.构造函数 析构函数 原型
构造函数:开辟内存空间
析构函数:释放内存空间
this:指向实例对象本身
原型:该类的公共存储空间,用于节省内存
function Book(name, author, price, type) {
// this指向实例对象本身
this.name = name;
this.author = author;
this.price = price;
this.type = type;
// 为了避免内存浪费,不建议方法写在构造函数
// this.sale = function() {
// console.log('全场8折');
// }
}
// 建议:方法及公用属性写在原型中
// 原型需要用构造函数名调用
// 原型的本质是个对象
Book.prototype.sale = function() {
console.log('全场8折');
}
var shz = new Book('水浒传', '施耐庵', '56.6', '小说');
var xyj = new Book('西游记', '吴承恩', '66.6', '小说');
3. 原型链
当访问对象的某个方法或属性时,现在自己的构造函数中查找,如果没有,在自己的原型中查找,如果还没有,查找原型的原型,一直找到Object的原型,这样形成的一个链条称之为原型链
function Dog(type, name, age) {
this.type = type;
this.name = name;
this.age = age;
}
Dog.prototype.skill = function() {
console.log('拆家');
}
function Cat(kindle, nick) {
this.tykindlepe = kindle;
this.nick = nick;
}
Cat.prototype = new Dog('金毛', '疙瘩', 2);
var cat = new Cat('橘猫', '啊桔');
cat.skill();
反转字符串
正常写法
function reverseString(string) {
return string.split('').reverse().join('');
}
面向对象写法
String.prototype.reverseString = function() {
return this.split('').reverse().join('');
}