面向对象编程的组合、多态、抽象类的基本介绍(二)

简介: 面向对象编程的组合、多态、抽象类的基本介绍

理解多态

有了上面的向上转型,动态绑定,方法重写之后,我们就可以使用多态的形式来设计程序了

我们可以写一些只关注父类的代码,就能够同时兼容各种子类的情况

代码示例:打印多种形状

class Shape {
    public void draw() {
        //啥都不用干
    }
}
class Cycle extends Shape {
    @Override
    public void draw() {
        System.out.println("○");
    }
}
class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("方块");
    }
}
class Flower extends Shape {
    @Override
    public void draw() {
        System.out.println("❀");
    }
}
********************分割线******************************************
public class Main {
    public static void drawMap(Shape shape) {
        shape.draw();
    }
    public static void main(String[] args) {
        Shape shape1 = new Cycle();
        Shape shape2 = new Flower();
        Shape shape3 = new Rect();
        drawMap(shape1);
        drawMap(shape2);
        drawMap(shape3);
    }
}

在这个代码中分割线上方的代码是类的实现者编写的,分割线下方的代码是类的调用者编写的

使用多态的好处是什么?

1)类调用者对类的使用成本进一步降低

  • 封装是让类的调用者不需要知道类的实现细节
  • 多态能让类的调用者连这个类的类型是什么都不必知道,只需要知道这个对象具有某个方法即可
    因此多态可以理解成封装的进一步,让类调用者对类的使用成本进一步降低

2)能够降低代码的“圈复杂度”,避免大量使用if-else

3)可扩展能力强

如果新增一种新的形态,使用多态的方式代码改动成本也比较低

class Triangle extends Shape {
  @Override
  public void draw() {
    System.out.println("△");
  }
}

向下转型

向上转型是子类对象转成父类对象,向下转型就是父类对象转成子类对象,相比于向上转型来说,向下转型没有那么常见

super关键字

前面的代码由于使用了重写机制,调用到的是子类的方法,如果在子类内部需要调用父类方法怎么办?可以使用super关键字

super表示获取到父类实例的引用

1)使用super来调用父类的构造方法

2)使用super来调用父类的普通方法

superthis的区别

结论用尽量简单的方式使对象进入可工作状态,尽量不要在构造器中调用方法(如果这个方法被子类重写,就会触发动态绑定,但是此时子类对象还没有构造完成),可能会出现一些隐藏的但又极难发现的问题

无论那种编程语言,多态的核心都是让调用者不必关注对象的具体类型,这是降低用户使用成本的一种方法

抽象类

语法规则

在刚才的打印图形例子中,我们发现父类Shape中的draw方法好像并没有实际的工作,主要的绘制图形都是由Shape各种子类的draw方法来完成的,像这种没有实际工作的方法,我们可以把他设计成一个抽象方法(abstract method),包含抽象方法的类我们称为抽象类

abstract class Shape {
  abstract public void draw();
}
  • 在draw方法前加上关键字abstract,表示一个抽象方法,同时抽象方法没有方法体(没有{ },不能执行具体代码)
  • 对于包含抽象方法的类,必须加上一个abstract关键字表示这是一个抽象类

注意事项

1)抽象类不能直接实例化

2)抽象方法不能是private

3)抽象类中可以包含其他非抽象方法,也可以包含字段,这个非抽象方法和普通方法的规则是一样的,可以被重写,也可以被子类调用

抽象类的作用

抽象类存在的最大意义就是为了被继承

抽象类本身不能被实例化,要想使用,只能创建该抽象类的子类,然后让子类重写抽象类中的抽象方法

使用抽象类相当于多了一重编译器的校验

使用抽象类的场景就如上面的代码,实际工作不应该由父类来完成,而应由子类来完成,那么此时如果不小心误用成父类了,使用普通类编译器是不会报错的,但是父类是抽象类在实例化的时候提示错误,让我们今早发现问题

很多语法存在的意义都是为了“预防出错”,例如我们曾经用过的final关键字,创建的变量用户不去修改,不就相当于常量吗?但是加上final,能够在不小心误修改的时候,让编译器提示我们

充分利用编译器的校验,在实际开放中非常有意义的

相关文章
|
13天前
|
C++
C++一分钟之-继承与多态概念
【6月更文挑战第21天】**C++的继承与多态概述:** - 继承允许类从基类复用代码,增强代码结构和重用性。 - 多态通过虚函数实现,使不同类对象能以同一类型处理。 - 关键点包括访问权限、构造/析构、菱形问题、虚函数与动态绑定。 - 示例代码展示如何创建派生类和调用虚函数。 - 注意构造函数初始化、空指针检查和避免切片问题。 - 应用这些概念能提升程序设计和维护效率。
21 2
|
2月前
|
安全 Java 程序员
面向对象——多态,抽象类,接口(二)-1
面向对象——多态,抽象类,接口(二)
20 1
|
2月前
|
Java
面向对象——多态,抽象类,接口(二)-2
面向对象——多态,抽象类,接口(二)
18 1
|
2月前
|
C#
C# 继承、多态性、抽象和接口详解:从入门到精通
在 C# 中,可以将字段和方法从一个类继承到另一个类。我们将“继承概念”分为两类: 派生类(子类) - 从另一个类继承的类 基类(父类) - 被继承的类 要从一个类继承,使用 : 符号。 在以下示例中,Car 类(子类)继承了 Vehicle 类(父类)的字段和方法:
54 2
|
2月前
|
编译器 C++
[C++] 面向对象的三大特性:封装、继承和多态
[C++] 面向对象的三大特性:封装、继承和多态
48 0
|
10月前
|
设计模式 数据安全/隐私保护
面向对象编程基础:封装、继承、多态与抽象的全面解析
面向对象编程基础:封装、继承、多态与抽象的全面解析
37 0
|
12月前
浅谈 面向对象三大特性:封装 继承 多态
浅谈 面向对象三大特性:封装 继承 多态
74 0
面向对象的封装,继承,多态(一)
面向对象的封装,继承,多态。
68 0
面向对象的封装,继承,多态(一)
|
Java 程序员 编译器
面向对象编程的组合、多态、抽象类的基本介绍(一)
面向对象编程的组合、多态、抽象类的基本介绍
面向对象编程的组合、多态、抽象类的基本介绍(一)

热门文章

最新文章