YuezhenQin / javase

Implement Data Structures and Algorithms (Sorting, Searching, Greedy, DP) from Sketch
2 stars 1 forks source link

OOP: 以类和对象作为组织代码的单元以及它的三大特性 #37

Open YuezhenQin opened 4 months ago

YuezhenQin commented 4 months ago

Everything is an object. It expresses that everything can be modeled as a combination of state and behavior.

封装 Encapsulation: 信息隐藏和数据访问保护

封装特性需要编程语言提供特殊的语法机制来实现(publicprivate关键字)。

YuezhenQin commented 3 months ago

继承 Inheritance: 如果多个类有一些相同的属性和方法,就可以讲这些相同的部分抽取到一个父类中,让子类继承父类,避免在子类中重复书写相同的代码

One trait would mask the other. - Gregor Mendel

为了实现继承特性,编程语言需要提供特殊的语法机制,例如 java 使用 extends 关键字实现继承。

Using extends: class B extends A

Using super(): to access fields of the base class, or to invoke methods and constructors of the base class

public abstract class A { //1.抽象类可以包含属性和方法
    private int x;
    private int y;
    public A(int x, int y) {
        this.x = x;
        this.y = y;
    }
    ...
   public abstract void do(); //抽象方法
}

public class B extends A { //2.抽象类不允许被实例化,只能被继承
    private int z;
    public B(int x, int y, int z) {
        super(x, y);
        this.z = z;
    }
    @Override
    public void do() {...} //3.编译器会要求子类必须实现抽象类(父类)中的所有抽象方法(抽象类的存在意义)
}

继承层次的隐患

Image

相比继承,组合+接口+委托有哪些优势?

继承主要有 3 个作用,表示 is-a 关系,支持多态特性,代码重复利用。is-a 关系可以通过 has-a 关系替代,多态特性可以通过接口支持,代码复用可以通过委托实现。

public interface Flyable { //1. 接口
    void fly();
}

public class Flyability { 
    @Override
    public void fly() {...}
}

public interface Tweetable {
    void tweet();
}

public class Tweetability implements Tweetable {
    @Override
    public void tweet() {...}
}

public class Sparrow implements Flyable, Tweetable {
    private Flyability f= new Flyability(); // 2. 组合

    @Override 
    public void fly() {
        flyability.fly(); //3. 委托
    }
}
YuezhenQin commented 1 month ago

多态 Polymorphism: 编译阶段调用父类,运行阶段调用子类替换 (override) 父类的版本

我们知道封装、继承特性都需要编程语言提供特殊的语法机制来实现,多态特性也是如此。

  1. 编程语言要支持继承。
  2. 编程语言要支持父类类型对象引用子类类型对象,接口类型的引用指向实现类类型的对象。
  3. 编程语言要支持子类重写父类中的方法。
YuezhenQin commented 1 month ago

抽象类和接口存在的意义

封装不稳定的实现细节,暴露稳定的接口。上游系统面向下游系统提供的接口编程,不依赖不稳定的实现细节,而依赖稳定的接口。这样当下游系统实现细节发生变化的时候,上游系统的代码也基本不需要改动。