03

阅读: 评论:0

03

03

文章目录

  • 一、继承
    • 1.1 继承的实现
    • 1.2 继承的好处和弊端
    • 1.3. Java中继承的特点
  • 二、继承中的成员访问特点
    • 2.1 继承中变量的访问特点
    • 2.2 super关键字
    • 2.3 继承中构造方法的访问特点
    • 2.4 继承中成员方法的访问特点
    • 2.5 super内存图
    • 2.6 方法重写
    • 2.7 方法重写的注意事项
  • 三、抽象类
    • 3.1抽象类的概述(理解)
    • 3.2抽象类的特点(记忆)
    • 3.3抽象类的案例
    • 3.4模板设计模式
    • 3.5 final关键字

一、继承

1.1 继承的实现

  • 继承的概念

    • 继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法
  • 什么是继承,如图:

  • 实现继承的格式

    • 继承通过extends实现
    • 格式:class 子类 extends 父类 { }
      • 举例:class Dog extends Animal { }
  • 继承带来的好处

    • 继承可以让类与类之间产生关系,子父类关系,产生子父类后,子类则可以使用父类中非私有的成员。
    • 注意:子类继承父类后,只能使用父类中非私有的成员
  • 示例代码

    public class Fu {public void show() {System.out.println("show方法被调用");}
    }
    public class Zi extends Fu {public void method() {System.out.println("method方法被调用");}
    }
    public class Demo {public static void main(String[] args) {//创建对象,调用方法Fu f = new Fu();f.show();Zi z = new Zi();z.method();z.show();}
    }
    

1.2 继承的好处和弊端

  • 继承好处

    • 提高了代码的复用性(多个类相同的成员可以放到同一个类中)

    • 提高了代码的维护性

      (如果方法的代码需要修改/增加,修改一处即可,可直接修改/增加父类中的成员变量)

  • 继承弊端

    • 继承是侵入性的

    • 降低了代码的灵活性

      解释:继承关系,导致子类必须拥有父类非私有的成员,让子类多了很多约束

    • 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性

  • 继承的应用场景:

    • 使用继承,需要考虑类与类之间是否存在is…a的关系(即存在相同的或者共性的内容),不能盲目使用继承
    • is…a的关系:谁是谁的一种
      • 例如:老师和学生是人的一种,那人就是父类,学生和老师就是子类
      • 猫和狗都是动物的一种,那动物就是父类,猫狗就是子类
    • 构造方法是特有的,不能提取到父类进行共享,因为构造方法与类名相同

1.3. Java中继承的特点

  • Java中继承的特点

    1. Java中类只支持单继承,不支持多继承(一个子类不能有多个父类)

      • 错误范例:class A extends B, C { }
    2. Java中类支持多层继承

      相当于:现在又A、B、C三个类,想要C继承A、B的属性,可以通过多层继承来实现

      • 多层继承的非私有化成员可以传递
  • 多层继承示例代码:

    public class Granddad {public void drink() {System.out.println("爷爷爱喝酒");}}public class Father extends Granddad {public void smoke() {System.out.println("爸爸爱抽烟");}}public class Mother {public void dance() {System.out.println("妈妈爱跳舞");}}
    public class Son extends Father {// 此时,Son类中就同时拥有drink方法以及smoke方法
    }
    

二、继承中的成员访问特点

2.1 继承中变量的访问特点

在子类方法中访问一个变量,采用的是就近原则

  1. 子类局部范围找
  2. 子类成员范围找
  3. 父类成员范围找
  4. 如果都没有就报错(不考虑父亲的父亲…)
  5. 如果都有该变量且重名的话,按就近原则优先考虑最近的

2.2 super关键字

由于想在子类中实现对父类成员的调用,此时可以使用super关键字
对于super关键字的应用场景可以参考这篇文章:
super关键字什么时候使用?super的适用场景是?_super关键字用在什么场合_❀༊烟花易冷ღ࿐❀的博客-CSDN博客

在类与对象中我们学习了this关键字,一以下是关于两者的区别:

  • -this&super关键字:

  • this:代表本类对象的引用

  • super:代表父类存储空间的标识(可以理解为父类对象引用)

  • this和super的使用分别

    • 成员变量:
      • this.成员变量 - 访问本类成员变量
      • super.成员变量 - 访问父类成员变量
    • 成员方法:
      • this.成员方法 - 访问本类成员方法
      • super.成员方法 - 访问父类成员方法
  • 构造方法:

    • this(…) - 访问本类构造方法

    • super(…) - 访问父类构造方法

2.3 继承中构造方法的访问特点

注意:子类中所有的构造方法默认都会访问父类中无参的构造方法

​ 子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化

​ 原因在于,每一个子类构造方法(有参无参构造方法都是)的第一条语句默认都是:super()

  • [关于构造方法 ]

问题:如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?

//1. 通过使用super关键字去显示的调用父类的带参构造方法//2. 子类通过this去调用本类的其他构造方法,本类其他构造方法再通过super去手动调用父类的带参的构造方法
  • 注意: this(…);与super(…) ;必须放在构造方法的第一行有效语句,并且二者不能共存
  • 如果是this.XXXX=XXXX;与super(…) ;就可以共存

2.4 继承中成员方法的访问特点

​ 在继承中,子类可以继承父类的所有成员,包括私有和非私有;但是子类只能访问父类中非私有的成员。(父子类间继承和访问不是一个概念

通过子类对象访问一个方法

  1. 子类成员范围找
  2. 父类成员范围找
  3. 如果都没有就报错(不考虑父亲的父亲…)

2.5 super内存图

  • 对象在堆内存中,会单独存在一块super区域,用来存放父类的数据

2.6 方法重写

  • 1、方法重写概念

    • 子类出现了和父类中一模一样的方法声明(方法名一样,参数列表也必须一样
  • 2、方法重写的应用场景

    • 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容
  • 3、Override注解

    • 用来检测当前的方法,是否是重写的方法(检查方法名和参数是否完全一致),起到【校验】的作用
      注意:方法重写 vs 方法重载
  • 方法重写: 在继承体系中,子类出现了和父类中一模一样的方法声明(方法名一样,参数列表也必须一样)

  • 方法重载: 同一个类中,方法名相同,参数列表不同,跟返回值无关

2.7 方法重写的注意事项

  • 方法重写的注意事项
  1. 私有方法不能被重写(父类私有成员子类是不能继承的)

  2. 子类方法访问权限不能更低(public > 默认 > 私有)


    3.静态方法不能被重写(父类和子类任何一个方法被static修饰都构不成重写)

三、抽象类

3.1抽象类的概述(理解)

​ 当我们在做子类共性功能抽取时,有些方法在父类中并没有具体的体现,这个时候就需要抽象类了!

  • ​ 在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类!
    • 而类中如果有抽象方法,该类必须定义为抽象类

3.2抽象类的特点(记忆)

  • 抽象类和抽象方法必须使用 abstract 关键字修饰

    • 抽象类
    • 格式:

//抽象类的定义 public abstract class 类名 {}

  • 抽象方法
  • 格式:

//抽象方法的定义 public abstract void eat();

  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

  • 抽象类不能实例化

    • 即抽象类不能创建新对象(在我们的主函数中)
  • 抽象类可以有构造方法

  • 抽象类的子类(以下两者只能选一个)

    • ​ 要么重写抽象类中的所有抽象方法

      • 子类继承抽象父类,父类有抽象方法和非抽象方法,此时子类必须重写父类中抽象的方法,对于父类中非抽象的方法,可以选择性是否重写
    • ​ 要么是抽象类

3.3抽象类的案例

  • 案例需求

    ​ 定义猫类(Cat)和狗类(Dog)

    ​ 猫类成员方法:eat(猫吃鱼)drink(喝水…)

    ​ 狗类成员方法:eat(狗吃肉)drink(喝水…)

  • 实现步骤

    1. 猫类和狗类中存在共性内容,应向上抽取出一个动物类(Animal)
    2. 父类Animal中,无法将 eat 方法具体实现描述清楚,所以定义为抽象方法
    3. 抽象方法需要存活在抽象类中,将Animal定义为抽象类
    4. 让 Cat 和 Dog 分别继承 Animal,重写eat方法
    5. 测试类中创建 Cat 和 Dog 对象,调用方法测试
  • 代码实现

    • 动物类
    public abstract class Animal {//提取猫类和狗类的共性drink()public void drink(){System.out.println("喝水");}//无参构造方法public Animal(){}//将不完全共性的eat()方法定义为抽象方法,以供子类进行独立重写public abstract void eat();
    }
    
    • 猫类
    public class Cat extends Animal {//方法重写@Overridepublic void eat() {System.out.println("猫吃鱼");}
    }
    
    • 狗类
    public class Dog extends Animal {//方法重写@Overridepublic void eat() {System.out.println("狗吃肉");}
    }
    
    • 测试类
    public static void main(String[] args) {Dog d = new Dog();d.eat();d.drink();Cat c = new Cat();c.drink();c.eat();//Animal a = new Animal();//a.eat();}
    

3.4模板设计模式

  • 设计模式

    设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

  • 设计模式的意义:使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。

  • 模板设计模式

    • 把抽象类整体就可以看做成一个模板,模板中不能决定的东西定义成抽象方法
    • 让使用模板的类(继承抽象类的类)去重写抽象方法实现需求
  • 模板设计模式的优势

    模板已经定义了通用结构,使用者只需要关心自己需要实现的功能即可

  • 示例代码

    模板类

    /*作文模板类*/
    public abstract class CompositionTemplate {public final void write(){System.out.println("<<我的爸爸>>");body();System.out.println("啊~ 这就是我的爸爸");}public abstract void body();
    }
    

    实现类A

    public class Tom extends CompositionTemplate {@Overridepublic void body() {System.out.println("那是一个秋天, 风儿那么缠绵,记忆中, " +"那天爸爸骑车接我放学回家,我的脚卡在了自行车链当中, 爸爸蹬不动,他就站起来蹬...");}
    }
    

    实现类B

    public class Tony extends CompositionTemplate {@Overridepublic void body() {}/*public void write(){}*/
    }
    

    测试类

    public class Test {public static void main(String[] args) {Tom t = new Tom();t.write();}
    }
    

3.5 final关键字

  • fianl关键字的作用

    • final代表最终的意思,可以修饰成员方法,成员变量,类
  • final修饰类、方法、变量的效果

    • fianl修饰类:该类不能被继承(不能有子类,但是可以有父类)

    • final修饰方法:该方法不能被重写

    • final修饰变量:表明该变量是一个常量,不能再次赋值

      • 变量是基本类型,不能改变的是值

      • 变量是引用类型,不能改变的是地址值(引用关系固定了),但地址里面的内容是可以改变的

      • 举例

public static void main(String[] args){final Student s = new Student(23);s = new Student(24);  // 错误s.setAge(24);  // 正确
}

本文发布于:2024-01-28 21:04:34,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170644708210270.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23