• Java基础35 面向对象三大特征之继承


    ● 继承基本介绍

    继承可以解决代码复用,让我们的编程更加靠近人类思维,当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。

    ● 继承的基本语法

    class 子类 extends父类{
         代码块
    }
    
    this()调用本类构造器
    super()调用父类构造器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1)子类会自动拥有父类定义的属性和方法。
    2)父类又叫基类,超类(Object)。
    3)子类又叫派生类。

    继承的好处:

    1)代码的复用性提高
    2)代码的扩展性和维护性提高

    ● 继承的深入细节

    1. this()调用本类构造器
      super()调用父类构造器
    2. 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问。
    3. 子类必须调用父类的构造器,完成父类的初始化。
    4. 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过。
    5. 如果希望指定去调用父类某个构造器,则显示的调用一下:super(参数列表)
    6. super在使用时,必须放在构造器第一行(super只能在构造器中使用)
    7. super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器中。
    8. java所有类都是Object类的子类,Object是所有类的超类(基类)。
    9. 父类构造器的调用不限于直接父类!将一直往上溯直到Object类(顶级父类)
    10. 子类最多继承一个父类(指直接继承),即java中是单继承机制

    例如:如何让A类继承B类和C类?【A继承B,B继承C】

    1. 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系。
    Person is a Music?
    Person Music
    Music extends Person //不合理
    
    Animal
    Cat extends Animal // 合理
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ● 继承的本质分析(☆)

    以下列代码为例:

    public class ExtendsTheory{
    	public static void main(String[] args){
    		Son son = new Son(); 
    		//按照查找关系来返回信息
    		//(1) 先看子类是否有该属性
    		//(2)如果子类有这个属性,并且可以访问,则返回信息
    		//(3)如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回该信息)
    		//(4)如果父类没有就按照(3)的规则,继续找上级父类,直到Object
    		System.out.println(son.name); //son有name属性,返回:大头儿子
    		System.out.println(son.age); //son没有age属性,向上级寻找,而父类中有age属性,则返回父类的age: 39。
    		System.out.println(son.hobby);//son与father都没有hobby属性,而爷类有,就返回爷类的信息: 旅游
    	}
    }
    class GrandPaP{ //爷类
    	String name = "大头爷爷";
    	String hobby = "旅游";
    }
    class Father extends GrandPa{ //父类
    	String name = "大头爸爸";
    	int age = 39;
    }
    class Son extends Father{
    	String name = "大头儿子";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    注意:继承最终输出是按照查找关系来返回信息

    	(1) 先看子类是否有该属性
    	(2)如果子类有这个属性,并且可以访问,则返回信息
    	(3)如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回该信息)
    	(4)如果父类没有就按照(3)的规则,继续找上级父类,直到Object
    
    • 1
    • 2
    • 3
    • 4

    以上面的例子,画出继承JVM内存布局

    在这里插入图片描述

    ● 继承练习

    练习1

    以下代码在main中,执行B b = new B(); 会输出什么?

    class A{
    	A(){
    		System.out.println("a");
    	}
    	A(String name){
    		System.out.println("a name");
    	}
    }
    class B extends A{
    	B(){
    		this("abc");
    		System.out.println("b");
    	}
    	B(String name){
    		System.out.println("b name");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    注意:
    B(String name){}中其实隐藏了一个super();
    所以最终输出答案为:a,b name,b

    练习2

    以下代码输出结果是什么?

    class A{
    	public A(){
    		System.out.println("我是A类");
    	}
    }
    
    class B extends A{
    	public B(){
    		System.out.println("我是B类的无参构造");
    	}
    	public B(String name){
    		System.out.println(name + "我是B类的有参构造");
    	}
    }
    
    class C extends B{
    	public C(){
    		this("hello");
    		System.out.println("我是C类的无参构造");
    	}
    	public C(String name){
    		System.out.println("我是C类的有参构造");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    分析:
    (1)从class C开始,【进入到 C的无参构造器】
    (2)this(“hello”);表示先执行本类的有参构造,【进入到C的有参构造器】
    (3)super(“hahaa”);代表进入到父类的有参构造,【进入到class B的有参构造】
    (4)在B的有参构造中隐藏了一个super,所以要【进入到A的无参构造】
    (5)返回第一个信息:我是A类
    (6)执行到到B有参,返回第二个信息:hahah我是B类的有参构造
    (7)执行到C有参,返回第三个信息:我是C类的有参构造。
    (8)执行回C无参,返回第四个信息:我是C类的无参构造。

    练习3

    1)编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息
    2)编写PC子类,继承Computer类,添加特有属性【品牌brand】
    3)编写NotePad子类,继承Computer类,添加特有属性【演示color】
    4)编写Test类,在main方法中创建PC和NotePad对象,分别给对象中特有的属性赋值,以及从Computer类继承的属性赋值,并使用方法且打印输出信息。

    Computer类

    public class Computer {
    //    1)编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息
        private String CPU;
        private int memory;
        private int disk;
    
        public Computer(String CPU, int memory, int disk) {
            this.CPU = CPU;
            this.memory = memory;
            this.disk = disk;
        }
    
        //getDetails方法用于返回Computer的详细信息
        public  String getDetailes(){
            return "cpu =" + CPU + "memory =" + memory + "disk =" + disk;
        }
    
        public String getCPU() {
            return CPU;
        }
    
        public void setCPU(String CPU) {
            this.CPU = CPU;
        }
    
        public int getMemory() {
            return memory;
        }
    
        public void setMemory(int memory) {
            this.memory = memory;
        }
    
        public int getDisk() {
            return disk;
        }
    
        public void setDisk(int disk) {
            this.disk = disk;
        }
    }
    
    • 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

    PC类

    public class PC extends  Computer{
    //    2)编写PC子类,继承Computer类,添加特有属性【品牌brand】
        private  String brand;
    
        //这里idea根据调用的规则,自动把调用的构造写好
        //这里也体现出 : 继承设计的基本思想,父类的构造器完成父类属性初始化
        //子类的构造器完成子类属性初始化
        public PC(String CPU, int memory, int disk, String brand) {
            super(CPU, memory, disk);
            this.brand = brand;
        }
    
        public void printInfo(){
            System.out.println("PC信息 =");
            //调用父类的getDetailes方法,得到相关属性信息。
            System.out.println(getDetailes() + "brand = " + brand);
        }
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    }
    
    • 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

    NotePad类

    public class NotePad extends  Computer{
    //    3)编写NotePad子类,继承Computer类,添加特有属性【演示color】
        private String color;
    
        public NotePad(String CPU, int memory, int disk, String color) {
            super(CPU, memory, disk);
            this.color = color;
        }
    
        public void  NoteInfo(){
            System.out.println("NotePad信息 = ");
            System.out.println(getDetailes() + "color = " + color );
        }
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    test类

    public class test {
    //    4)编写Test类,在main方法中创建PC和NotePad对象,分别给对象中特有的属性赋值,
    //    以及从Computer类继承的属性赋值,并使用方法且打印输出信息。
        
        public static void main(String[] args) {
            PC pc = new PC("intel",16,500,"IBM");
            pc.printInfo();
    
            NotePad note = new NotePad("intel",32,500,"yellow");
            note.NoteInfo();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    输出

    在这里插入图片描述

  • 相关阅读:
    java计算机毕业设计花卉网站源码+mysql数据库+系统+lw文档+部署
    Go Sync并发包之errgroup
    ENVI IDL:MODIS SWATH产品的点位-像元提取(另附Python代码)
    JavaScript-变量的作用域、let、const详解
    人工智能:从图灵到未来
    stable diffusion绘制汉服美女
    基于Springboot的校园健康系统-计算机毕业设计源码
    JVM第十七讲:调试排错 - Java 问题排查之Linux命令
    CCRC-DSO学员分享:数据安全官——导师与朋友的双重身份
    RNN 单元:分析 GRU 方程与 LSTM,以及何时选择 RNN 而不是变压器
  • 原文地址:https://blog.csdn.net/chenjiap/article/details/126936812