六.面向对象
面向对象
面向对象是针对面向过程的不足推出的一种开发思想,任何事物都可以看作是一个对象。面向对象也被称之为OOP(Object Oriented Programming)。分开来解读就是:
Object:对象;
Oriented: 面向的;
Programming:程序设计。
同时面向对象还具有以下的优点:
- 代码开发模块化,便于维护。
- 代码复用性强
- 代码的可靠性和灵活性。
- 代码的可读性和可扩展性。
面向对象的三大特性:
1、封装性:
隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。
2、继承:
提高代码复用性;继承是多态的前提。
3、多态:
父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。
封装性:
封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
- 简单的来说就是我将不想给别人看的数据,以及别人无需知道的内部细节, “锁起来” ,我们只留下一些入口,使其与外部发生联系。
我们如何给我们的数据 “上锁” 呢?
- 我们使用,public、private、protected 等权限修饰符 在类的内部设定了边界,这些不同程度的 ”锁“ 决定了紧跟其后被定义的东西能够被谁使用。
封装的好处
隐藏实现细节,提供公共的访问方式,提高了代码的复用性,提高安全性
好处1:隐藏实现细节,提供公共的访问方式
隐藏实现细节怎么理解呢?
-
我们将一些功能封装到类中,而客户端的程序员,不需要知道类中的这个方法的逻辑原理,类程序员只需要给他一个对外的接口,客户端程序员只需要能够调用这个方法即可,
-
例如:想吃披萨,我们(用户)只需要点餐厨师做好就可以了,并不需要了解披萨是如何制作的
提供公共的访问方式又怎么理解呢?
我们先来看一段标准案例
public class Pizza {
//定义私有的披萨属性: 名称、价格、大小
private String name;
private double price;
private int size;
//成员变量的set和get方法(对外提供的公共访问方式)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
//有参构造方法
public Pizza(String name, double price, int size) {
super();
this.name = name;
this.price = price;
this.size = size;
}
//无参构造方法
public Pizza() {
super();
}
}
由此可以看出,成员变量都使用 private 修饰,而下面的 get 和 set 方法均使用了public修饰,其实被private修饰的属性就是我们想要锁起来的数据,而 set、get 方法就是我们打开这把锁的钥匙
被private所修饰的内容是,除类型创建者和类型的内部方法之外的任何人都不能访问的元素,所以我们这些数据就被我们通过private “锁” 了起来,而我们外界是可以通过创建对象来调用一个类中的公共方法的,所以被 public修饰的 set 和 get 方法外界所能访问的,而这两个方法又可以直接访问我们的私有成员变量,所以 set 和 get 方法就成为了私有成员与外界沟通的钥匙。
好处2:提高了代码的复用性
功能被封装成了类,通过基类与派生类之间的一些机制(组合和继承),来提高代码的复用性
继承:
继承是一种由已有的类创建新类的机制。利用继承, 我们可以先创建一个共有属性的一般类,根据该一般 类再创建具有特殊属性的新类,新类继承一般类的状态和行为,并根据需要增加它自己的新的状态和行为。同时不要为了继承而继承,只有当类之间有关联的时候再继承。
继承的好处
提高了代码的复用性,提高了代码的维护性(通过少量的修改,满足不断变化的具体要求),让类与类产生了一个关系,是多态的前提。但是缺点也很显著:让类的耦合性增强,这样某个类的改变就会影响其他和该类相关的类。
继承的关键字extends
覆盖&重写:
不管是普通汽车,还是卡车和轿车,他们的运转都是 样的,结果均输出“汽车在奔跑”,这是不恰当的
车和轿车的运转应该是有自己的独立方式的,不应当和普通汽车保持一致。
也就是说,子类需要对父类的run方法加以改进,变 成子类自己的run方法,这就需要在子类中重新编写
run方法,覆盖父类的run方法,这种做法在Java中叫 覆做方法的覆盖(Override,又称方法重写)
重载和重写的区别:
要注意重载和重写的区别,重载既可以发生于一个类, 也可以发生于子类与父类之间(子类继承父类方法, 同时完成方法重载),而重写,则只能是子类重写父 类方法
注意:
- 子类只能继承父类所有非私有成员(成员方法和成员变量)
- 子类不能继承父类的构造方法,但是可以通过super关键字去访问方法
- 不要为了部分功能而继承(多层继承会使得子类继承多余的方法)