MENU

继承

November 23, 2021 • 编程,JAVA阅读设置

基本概念

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
  • extends的意思是“扩展”。子类是父类的扩展
  • JAVA 中类只有单继承,没有多继承

    • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖/组合/聚合等
    • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字 extends 来表示
    • 子类和父类之间,从意义上讲应该具有“is a”的关系
    • 构造一个子类一定会先构造一个父类
    • 快捷键 Ctrl+ H:继承树
//在java中,所有的类都默认直接或间接继承Object类
public class Person /*extends Object*/{

    //public
    //private
    //protected 受保护的
    //default 默认权限
    public int money = 100_100_000;
    public void say(){
        System.out.println("说了一句话");
    }

    private int wallant = 500;

    public int getWallant() {
        return wallant;
    }

    public void setWallant(int wallant) {
        this.wallant = wallant;
    }
}

//学生 is 人:子类/派生类 is 父类/基类
//子类继承了父类,就会拥有父类的全部方法
public class Student extends Person{
    //Ctrl + H:继承树

}
在 java 中,所有的类都默认直接或间接继承Object 类

Super

  • 在子类中调用父类的非私有属性和方法时,大致的过程如下:

    1. 先在当前类中寻找。
    2. 当前类没有,继续向父类中寻找。
    3. 如果还是没有,就向父类的父类继续寻找。
    4. 直到到达一个所有类的共同父类,它叫 Object。

super 相当于是指向父类的 this,但私有(private)的东西无法被调用

public class Student extends Person{

    private String name = "张";

    public void test(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);

        print();
        this.print();
        super.print();
    }
}


public class Person /*extends Object*/{

    protected String name = "张卓玮";
}


public class Application {

    public static void main(String[] args) {
        com.oop.demo05.Student cool = new com.oop.demo05.Student();
        cool.test("aaa");
    }
}

//输出结果
aaa
张
张卓玮
Student
Student
Person

注意点

  • super 调用父类的构造方法,必须在构造方法的第一个
  • super 必须只能出现在子类的方法或者构造方法中
  • super 和 this 不能同时调用构造方法
public class Student extends Person{

    public Student() {
        //隐藏代码:默认调用了父类的无参构造
        //super();
        //调用父类的构造器,必须要在子类构造器的第一行
        System.out.println("Student无参构造执行了");
    }
}


public class Person /*extends Object*/{

    public Person() {
        System.out.println("Person无参构造执行了");
    }
}


public class Application {

    public static void main(String[] args) {
        com.oop.demo05.Student cool = new com.oop.demo05.Student();
        cool.test("aaa");
    }
}

//输出结果
Person无参构造执行了
Student无参构造执行了

和 this 的区别

  • 代表的对象不同

    this:本身调用者这个对象

    super:代表父类对象的引用

  • 前提

    this:没有继承也可以使用

    super:只能在继承条件下才能使用

  • 构造方法

    this():本类的构造

    super():父类的构造(不会向上检索)

thissuper
访问属性访问本实例的属性,没有会继续向父类检索访问父类实例的属性,没有会继续向父类检索
调用方法访问本实例的方法,没有会继续向父类检索访问父类实例的方法,没有会继续向父类检索
调用构造器调用本类的构造器,必须放在第一行,不会向上检索调用父类的构造器,必须放在第一行,不会向上检索

方法重写

重写的意义:父类的功能,子类不一定需要,或者不一定满足
  • 重写需要有继承关系,子类重写父类的方法
  • 重写都是方法(方法名和参数列表必须相同)的重写,与属性无关
  • 修饰符范围可以扩大但不能缩小(重写的关键词不能是私有(private)的):public>protected>default>private
  • 抛出异常:范围可以被缩小,但不能扩大
  • 向上转型:

    • 父类的引用指向了子类(如下例,b 是子类的引用,new A()构造的是一个父类的对象)
    • 静态方法的调用只和左边,定义的数据类型有关
    //重写都是方法的重写,和属性无关
    public class A extends B{
    
        public static void test(){
    
            System.out.println("A==>test()");
        }
    }
    
    public class B {
        public static void test() {
            System.out.println("B==>test()");
        }
    }
    
    
    
    public class Application {
    
        public static void main(String[] args) {
    
            //静态方法的调用只和左边,定义的数据类型有关
            A a = new A();
            a.test();
    
            //向上转型:父类的引用指向了子类-->b是子类的引用,new A()构造的是一个父类的对象
            B b = new A();
            b.test();
    
        }
    }
    
    
    //输出结果
    A==>test()
    B==>test()
    
  • 静态方法和非静态方法区别很大

    • 结合上例分析:

      b 是 A new 出来的对象,因此调用了 A 的方法

      因为静态方法是类的方法,而非静态是对象的方法

      有 static 时,b 调用了 B 类的方法,因为 b 是用 B 类定义的

      没有 static 时,b 调用的时对象的方法,因为 b 是用 A 类 new 的

    //重写都是方法的重写,和属性无关
    public class A extends B{
    
        @Override//注解:有功能的注释
        public void test(){
    
            System.out.println("A==>test()");
        }
    }
    
    public class B {
        public void test() {
            System.out.println("B==>test()");
        }
    }
    
    
    
    public class Application {
    
        public static void main(String[] args) {
    
            A a = new A();
            a.test();
    
            B b = new A();//子类重写了父类的方法
            b.test();
    
        }
    }
    
    
    //输出结果
    A==>test()
    A==>test()
Last Modified: February 6, 2023