面向对象的三个特性(封装、继承、多态)
封装
封装是指一种将抽象性函数式接口的实现细节包装、隐藏起来的方法。封装可以防止该类的代码和数据被外部定义的代码随机访问到。要访问该类的代码和数据必须要通过严格的接口控制。
封装主要功能在于我们能修改自己的实现代码,而不是修改那些我们调用的程序片段。适当的封装可以让程序代码更容易理解和维护,提高了程序代码的安全性。
优点:
- 良好的封装能够减少耦合
- 类内部的结构可以自由修改
- 隐藏实现细节和信息
- 可以精细操作成员变量
实现封装的步骤
-
修改属性的可见性来限制对属性的访问
public class Person{ private int age; private String name; }
-
对每个值提供对外的公共方法访问,也就是创建一对取值和赋值的方法。get/set
public class Person{ private String name; private int age; public int getAge(){ return age; } public String getName(){ return name; } public void setAge(int age){ this.age = age; } public void setName(String name){ this.name = name; } }
应用的方法较多的为 实体类。
继承
概念
子类继承父类的特征和行为,使得子类对象具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
class 父类{
}
class 子类 extends 父类{
}
继承可以看做从大到小,从粗到细的过程。由简单划分的领域细化的过程。
继承类型
java支持多重继承,但不支持多继承。即一个java子类不能同时继承多个父类。
// 单继承
public class A{}
public class B extends A{}
// 多重继承
public class A{}
public class B extends A{}
public class C extends B{}
//不同类继承同一个类
public class A{}
public class B extends A{}
public class C extends A{}
虽然不能多继承,但可以通过多重继承的方式来实现多继承。
继承的特性
- 子类拥有父类 非 private 的属性和方法。
- 子类可以拥有自己的属性和方法,即可以进行扩展
- 子类可以用自己的方式实现父类的方法。
- 缺点是提高了类的耦合,代码独立性变差
关键字
extends
extends只能继承一个类
implements
实现,使用implements关键字可以变相使java具有多继承的特性,但需要继承的都是接口( interface ),可以同时继承多个接口,用逗号分隔。
public interface A{}
public interface B{}
public class C implements A,B{}
super 与 this
super:可以通过super关键字来实现对父类成员的额访问,用来引用当前对象的父类。
this:指向自己的引用。
class Animal{
void eat(){
System.out.println("animal");
}
}
class Dog extends Animal{
void eat(){
System.out.println("dog");
}
void eatTest(){
this.eat(); // 调用自己的方法
super.eat(); // 调用父类的方法
}
}
final
final关键字声明类可以把类定义为不可继承,即最终类,或用于修饰方法,表示该方法不可被子类重写。
final class 类{}
修饰符(public/private/default/protected) final 返回值类型 方法名(){}
构造器
子类不继承父类的构造器,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super关键字调用父类的构造器并配以适当的参数列表。
如果父类构造器没有参数,则在子类的构造器中不需要super关键字调用父类构造器,系统会自动调用父类的无参构造器。
多态
多态是同一个行为具有多个不同表现形式或形态的能力。是同一个接口,使用不同的实例而执行不同的操作。
优点
- 消除类型间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
存在的三个必要条件
-
继承
-
重写
-
父类引用指向子类对象
Parent p = new Child();
示例
class Shape {
void draw() {}
}
class Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}
}
class Square extends Shape {
void draw() {
System.out.println("Square.draw()");
}
}
class Triangle extends Shape {
void draw() {
System.out.println("Triangle.draw()");
}
}
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处是可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
虚函数
虚函数的存在是为了多态。
java中其实没有虚函数的概念,它的普通函数相当于 C++的虚函数,动态绑定是java的默认行为。如果java中不希望某个函数具有虚函数特性,可以加 final 关键字变成非虚函数。
重写
当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。要调用父类中被重写的方法,必须使用 super 关键字。