不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • Java基础

  • 面向对象

    • 01.方法
    • 02.类和对象
    • 03.封装继承多态
      • 01.封装
      • 02.继承
        • 1、基本使用
        • 2、 四种修饰符
        • 1、src/cls/Parent.java
        • 2、src/cls/Child.java
        • 3、src/cls/Test.java
        • 3、super与this
        • 4、final
      • 03.多态
        • 1、多态举例
        • 2、向下转型
        • 3、instanceof
      • 04.abstract抽象类
        • 1、作用
        • 2、举例
    • 04.接口
  • Java进阶

  • Web基础

  • Spring框架

  • 微服务

  • Java
  • 面向对象
xiaonaiqiang
2021-11-16
目录

03.封装继承多态

# 01.封装

  • 作用:
    • 封装是将数据(变量)和操作数据的方法(函数)打包在一起,形成一个类(Class)
    • 封装的目的是隐藏对象的内部细节,仅暴露出必要的操作接口
    • 这样可以减少外部对对象内部的直接访问,降低耦合度,提高安全性和易用性
public class BankAccount {
    private double balance;  // 账户余额,私有属性,封装

    public BankAccount(double initialBalance) {
        balance = initialBalance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }

    public void withdraw(double amount) {
        if (amount > 0 && balance >= amount) {
            balance -= amount;
        }
    }

    public double getBalance() {
        return balance;
    }

    public static void main(String[] strings) {
        double balance = 19999.9;
        BankAccount ba = new BankAccount(balance);
        System.out.println( ba.getBalance() );
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 02.继承

  • Java 中的继承为单一继承,也就是说,一个子类只能拥有一个父类,一个父类可以拥有多个子类
  • 另外,所有的 Java 类都继承自 Java.lang.Object,所以 Object 是所有类的祖先类
  • 子类一旦继承父类,就会继承父类所有开放的特征,不能选择性地继承父类特征

# 1、基本使用

  • 重写方法的参数列表应该与原方法完全相同
  • 返回值类型应该和原方法的返回值类型一样或者是它在父类定义时的子类型
  • 重写方法访问级别限制不能比原方法高
    • 例如:如果父类方法声明为公有的,那么子类中的重写方法不能是私有的或是保护的
  • 方法定义为 final,将不能被重写(final 关键字将在本节后面讲到)
  • 一个方法被定义为 static,将使其不能被重写,但是可以重新声明
  • 和父类在一个包中的子类能够重写任何没有被声明为 private 和 final 的父类方法
  • 和父类不在同一个包中的子类只能重写 non-final 方法或被声明为 public 或 protected 的方法
  • 一个重写方法能够抛出任何运行时异常,不管被重写方法是否抛出异常
  • 构造方法不能重写
package day01;

class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
    public void say() {
        System.out.println(name + " say 基类 Animal");
    }

    public void sayHi() {
        System.out.println(name + " sayHi 基类 Animal");
    }
}

class Dog extends Animal {
    // 子类会继承父类的所有非私有(public和protected)属性和方法
    protected int age;

    // 子类不继承父类构造器,可通过super关键字调用父类构造器
    public Dog(String name, int age) {
        super(name);
        this.name = name;
        this.age = age;
    }

    // 子类可以直接使用这些方法和属性,也可以覆盖(override)这些方法
    @Override
    public void say() {
        System.out.println(name + age + " Dog 继承 Animal");
    }

    public void eat() {
        System.out.println(name + " eat ...");
    }
}

public class Test {
    public static void main(String[] args) {
        Dog myDog = new Dog("阿黄", 11);
        myDog.sayHi();  // 阿黄 sayHi 基类 Animal
        myDog.say();  // 阿黄11 Dog 继承 Animal
        myDog.eat();  // 阿黄 eat ...
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

# 2、 四种修饰符

  • 1、private:私有的,只允许在本类中访问
  • 2、protected:受保护的,允许在同一个类、同一个包以及不同包的子类中访问
  • 3、默认的:允许在同一个类,同一个包中访问
  • 4、public:公共的,可以再任何地方访问
访问控制修饰符 同一个类 同一个包 不同包的子类 不同包的非子类
private(私有的) ✓ ✕ ✕ ✕
default(默认的) ✓ ✓ ✕ ✕
protected(受保护的) ✓ ✓ ✓ ✕
public(公共的) ✓ ✓ ✓ ✓

# 1、src/cls/Parent.java

package cls;

// 父类
class Parent {
    // 私有的,只允许在本类中访问
    private String privateField = "private field";
    // 受保护的,允许在同一个类、同一个包以及不同包的子类中访问
    protected String protectedField = "protected field";
    // 允许在同一个类,同一个包中访问
    String defaultField = "default field";
    // 公共的,可以再任何地方访问
    public String publicField = "public field";

    // 私有的,只允许在本类中访问
    private void privateMethod() {
        System.out.println("private method in Parent");
    }

    // 受保护的,允许在同一个类、同一个包以及不同包的子类中访问
    protected void protectedMethod() {
        System.out.println("protected method in Parent");
    }

    // 允许在同一个类,同一个包中访问
    void defaultMethod() {
        System.out.println("default method in Parent");
    }

    // 公共的,可以再任何地方访问
    public void publicMethod() {
        System.out.println("public method in Parent");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 2、src/cls/Child.java

package cls;

// 子类,不同包中的子类
class Child extends cls.Parent {
    public void accessFieldsAndMethods() {
        // System.out.println(privateField); // 编译错误,无法访问父类的private字段
        System.out.println(protectedField);
        System.out.println(defaultField);
        System.out.println(publicField);

        // privateMethod(); // 编译错误,无法访问父类的private方法
        protectedMethod();
        defaultMethod();
        publicMethod();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 3、src/cls/Test.java

package cls;

public class Test {
    public static void main(String[] args) {
        Child child = new Child();
        child.accessFieldsAndMethods();
    }
}
1
2
3
4
5
6
7
8

# 3、super与this

  • super 是用在子类中的,目的是**访问直接父类**的变量或方法
    • super 关键字只能调用父类的 public 以及 protected 成员
    • super 关键字可以用在子类构造方法中调用父类构造方法
    • super 关键字不能用于静态 (static) 方法中
  • this 关键字指向**当前类对象的引用**,它的使用场景为
    • 访问当前类的成员属性和成员方法
    • 访问当前类的构造方法
    • 不能在静态方法中使用
package cls;

class Parent {
    String name;

    public Parent(String name) {
        this.name = name;
    }

    public void greet() {
        System.out.println("Parent.greet " + this.name);
    }
}

class Child extends Parent {
    public Child(String name) {
        super(name);
        this.name = name;
    }

    @Override
    public void greet() {
        System.out.println("Child.greet " + this.name);
    }

    public void greetBoth() {
        this.greet();  // Outputs: Child.greet Tom
        super.greet(); // Outputs: Parent.greet Tom
    }
}

public class Test {
    public static void main(String[] args) {
        Child child = new Child("Tom");
        child.greetBoth();
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 4、final

  • 当父类中方法不希望被重写时,可以将该方法标记为 final
class SuperClass {
    public final void finalMethod() {
        System.out.println("我是final方法");
    }
}

class SubClass extneds SuperClass {
    // 被父类标记为final的方法不允许被继承,编译会报错
    @Override
    public void finalMethod() {
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# 03.多态

  • 多态意味着允许不同类的对象对同一消息做出不同的响应

  • 例如

    • 火车类和飞机类都继承自交通工具类,这些类下都有各自的run()方法
    • 而火车的run()方法输出火车会跑,飞机的run()方法则输出飞机会飞
    • 火车和飞机都继承父类的run()方法,但是对于不同的对象,拥有不同的操作

# 1、多态举例

public class Test{
    public static void main(String args[]){
        Animal dog = new Dog();
        Animal cat = new Cat();
        dog.eat();
        cat.eat();
    }
}

class Animal {
    // 定义方法 eat
    public void eat() {
        System.out.println("宠物吃东西");
    }
}

class Dog extends Animal { // 继承父类
    // 重写父类方法 eat
    public void eat() {
        System.out.println("狗狗吃狗粮");
    }
}

class Cat extends Animal { // 继承父类
    // 重写父类方法 eat
    public void eat() {
        System.out.println("猫猫吃猫粮");
    }
}

/*
狗狗吃狗粮
猫猫吃猫粮
 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 2、向下转型

  • 向上转型是父类引用指向子类实例,那么如何让子类引用指向父类实例呢?使用向下转型就可以实现
  • 我们为Dog类新增了一个run方法,此时我们无法通过Animal类型的dog实例调用到其下面特有的run方法
  • 需要向下转型,通过(Dog)dog将Animal类型的对象强制转换为Dog类型,这个时候就可以调用run方法了
package cls;

public class Test{
    public static void main(String[] args){
        Animal d = new Dog();
        d.eat();
        // dog.run()  // 这个调用就是错误的
        ((Dog) d).run();
    }
}

class Animal {
    // 定义方法 eat
    public void eat() {
        System.out.println("宠物吃东西");
    }
}

class Dog extends Animal { // 继承父类
    // 重写父类方法 eat
    public void eat() {
        System.out.println("狗狗吃狗粮");
    }

    public void run() {
        System.out.println("狗狗跑得快");
    }
}

/*
狗狗吃狗粮
狗狗跑得快
 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 3、instanceof

  • instanceof运算符用来检查对象引用是否是类型的实例,或者这个类型的子类,并返回布尔值
package com.case_01;

public class Test{
    public static void main(String args[]){
        Animal animal = new Dog();
        if (animal instanceof Dog){
            // 将父类转换成子类
            Dog dog = (Dog) animal;
            dog.run();
        }
    }
}

class Animal {
    // 定义方法 eat
    public void eat() {
        System.out.println("宠物吃东西");
    }
}

class Dog extends Animal { // 继承父类
    // 重写父类方法 eat
    public void eat() {
        System.out.println("狗狗吃狗粮");
    }

    public void run() {
        System.out.println("狗狗跑得快");
    }
}

/*
狗狗跑得快
 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 04.abstract抽象类

# 1、作用

  • abstract 是一个关键字,用来创建抽象类和抽象方法

  • 抽象类

    • 抽象类是的,只能作为其他类的父类

    • 抽象类可以包含抽象方法和非抽象方法

  • 抽象方法

    • 抽象方法是只有声明,没有实现的方法

    • 包含抽象方法的类必须被声明为抽象类

    • 子类必须实现父类的所有抽象方法,除非子类也是抽象类

# 2、举例

  • 在这个例子中,Animal 是一个抽象类
  • 它有一个抽象方法 makeSound() 和一个非抽象方法 eat()
  • Dog 和 Cat 是 Animal 的子类,它们都实现了 makeSound() 方法我们可以看到
  • 即使 Dog 和 Cat 没有定义 eat() 方法,但是它们仍然可以调用 eat() 方法
  • 因为这个方法是从 Animal 类继承来的
package cls;

public class Test{
    public static void main(String[] args){
        Dog myDog = new Dog(); // 创建 Dog 对象
        myDog.makeSound(); // 调用 Dog 的 makeSound() 方法
        myDog.eat(); // 调用 Animal 的 eat() 方法

        Cat myCat = new Cat(); // 创建 Cat 对象
        myCat.makeSound(); // 调用 Cat 的 makeSound() 方法
        myCat.eat(); // 调用 Animal 的 eat() 方法
    }
}

// 抽象类
abstract class Animal {
    // 抽象方法
    abstract void makeSound();

    // 非抽象方法
    public void eat() {
        System.out.println("The animal eats");
    }
}

// Dog 类继承 Animal 类
class Dog extends Animal {

    // 实现 makeSound 方法
    public void makeSound() {
        System.out.println("The dog barks");
    }
}

// Cat 类继承 Animal 类
class Cat extends Animal {

    // 实现 makeSound 方法
    public void makeSound() {
        System.out.println("The cat meows");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
上次更新: 2024/5/31 11:18:42
02.类和对象
04.接口

← 02.类和对象 04.接口→

最近更新
01
06.Mage平台
05-30
02
16.区块链交易所
05-28
03
01.常识梳理
05-28
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式