- 良好的封装能够减少耦合
- 类内部的结构可以自由修改
- 可以对成员变量进行更精确的控制
- 隐藏信息,实现细节
setter()/getter()
分析内存后发现,当一个子类被实例化的时候,默认会先调用父类的构造方法对父类进行初始化,即在内存中创建一个父类对象,然后在父类对象的外部放上子类独有的属性,两者合起来成为一个子类的对象
所以,子类继承了父类的所有属性和方法或子类拥有父类的所有属性和方法是对的,只不过父类的私有属性和方法,子类是无法直接访到的,这也是 private 修饰符所控制的
属性没有多态的概念,在 java中 只有普通实例方法才可以实现多态
非 private、static 修饰的方法可以实现运行时的多态
多态的优点:解耦、可替换性、可扩充性、接口性、灵活性、简化性
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
}
else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
overwrite:重写,也叫覆盖、覆写,override。
overload:重载
区别 | 重载 | 重写 |
---|---|---|
参数列表 | 必须不同 | 必须相同 |
返回类型 | 可以不同 | 相同或为其派生类 |
抛出异常 | 可以不同 | 可以减少,不能更多 |
访问权限 | 可以不同 | 可以放宽,不能更严 |
向上转型 upcast
向上转型即父类引用指向子类对象,使该引用具有子类特性和父类共性
Son s = new Son();
Father f = s;
子类重写了父类的非静态方法,用 s
和 f
访问时,实际调用的都是子类中的对应方法
静态方法不能被重写,但是子类可以声明同名方法,用 s
访问时,访问到的是子类成员,用 f
访问时,访问到的是父类成员,这被称之为“隐藏”,并非覆盖
子类可以声明和父类相同的成员变量,且不会覆盖父类属性,这也是一种“隐藏”。在使用变量时,具体是父类还是子类的成员,取决于方法所在类
向下转型 downcast
使用强制类型转换 (Son)f
可以访问的子类的所有属性和方法
接口和类区别
接口和抽象类
接口特性
jdk8 接口新特性:
接口中能使用 default 修饰方法,称默认方法或扩展方法
默认方法可以有方法体,不一定要被重写
如果实现两个接口有同名的默认方法,则必须要在实现类中重写
接口中能使用静态方法,可以有方法体,使用方式接口名 . 方法名