java之继承

发布时间 2023-05-29 23:18:00作者: 踏浪而来的人

继承:实现代码的复用

子类继承父类的属性和方法,也可以覆写父类的属性和方法。

格式:

  class 父类{ }

  class 子类 extends 父类 { }  

 

实例化子类对象时,先调用父类的构造方法,再调用子类的构造方法(构造方法的目的是类属性的初始化);

为什么要先调用父类的构造方法呢?

因为子类继承了父类,且父类中的属性也要初始化,所以要先调用父类的构造方法,初始化父类中的属性

class Person {
    private int age;

    public void setAge(int age) {
        if (age < 0 || age > 200)
            age = 0;
        else {
            this.age = age;
        }
    }

    public int getAge() {
        return age;
    }    

    public void printInfo() {
        System.out.println("age = "+age);
    }

    public Person () {
     System.out.println("Person ()");
}
public Person (int age) { System.out.println("Person (int age)"); this.age = age; } } class Student extends Person{ private String school; public void setSchool(String school) { this.school = school; } public String getSchool() { return school; } public Student(String school) { /* will call the super() */ //super();//如果子类调用父类中默认的构造方法,super()写不写都行 super(5); //如果子类调用父类中带参数的构造方法,super就必须写,且还要带参数 System.out.println("Student(String school)"); this.school = school; } /* override */ public void printInfo() {//方法的重载 System.out.println("school = "+school+"; age = "+getAge()); } } public class Ext4 { public static void main (String args[]) { Student stu = new Student("ustc"); //stu.setAge(10); System.out.println(stu.getAge()); System.out.println(stu.getSchool()); stu.printInfo();//子类中有实现printInfo方法,就调用子类中的方法;如果没有实现,将会调用父类中的方法 } }

 

super关键字:

  1. 子类的构造方法里会默认调用super()

  2. 可以在子类构造方法中首行自行调用super(),可加参数

  3. super表示父类,可以用super.xxxx调用父类方法

final关键字:

  1. 被final修饰的类不能有子类

  2. final方法不能被覆写

  3. final变量变成常量,不能被修改

 

继承的限制:

  1. 父类中的私有属性不能被子类访问

  2. 父类中的私有方法不能被子类访问

  3. 子类覆写的方法不能缩小父类方法的权限

class Father {
    private int money;// 1.父类中的私有属性不能被子类访public int getMoney() {return money; }
    public void setMoney(int money) {this.money = money; }

    public void printInfo() {System.out.println("This is Father");}

    private void printInfo2() {System.out.println("This is Father");}//2. 父类中的私有方法不能被子类访问
}

class Son extends Father{
    private void printInfo() {System.out.println("This is son");}//会出错,编译不过,因为3.子类覆写的方法不能缩小父类方法的权public void printInfo2() {System.out.println("This is Father");}//printInfo2不是对父类中printInfo2方法的复写
                                        //因为父类中的方法是私有的,子类都不知道有这个方法,这个是子类自己实现的方法 }
public class Ext5 { public static void main (String args[]) { Son son = new Son(); son.setMoney(100);//由于money是父类中私有的属性,所以不能用son.money=100,即1.父类中的私有属性不能被子类访//son.printInfo(); } }

 

抽象类:规定子类必须实现的方法,起“模板”作用

格式:

abstract class 类名 {
    属性;
    普通方法 { }
    
    // 抽象方法
    访问权限  abstract 返回值类型 方法名 (参数) ; /* 只需要声明,不需要实现 */
}

  1. 抽象类不能实例化对象

  2. 子类必须覆写全部抽象方法(子类要实现全部的抽象方法)

abstract class Father {//抽象类
    private int money;    

    public int getMoney() {return money; }
    public void setMoney(int money) {this.money = money; }

    public abstract void study();//抽象方法
}

class Son extends Father{
    public void study() {System.out.println("I am study"); }//2. 子类要实现全部的抽象方法
    
}

public class Ext6 {
    public static void main (String args[]) {
        //Father f = new Father();//1. 抽象类不能被实例化对象,会编译出错
        Son son = new Son();
        son.study();
    }
}

 

接口:跟抽象类相似,起“模板”作用;子类可以实现(implement)多个接口,突破“单继承”的限制

格式:  

// 接口由全局常量、公共的抽象方法组成
interface 接口名称 {
    全局常量;
    抽象方法;
}

如:interface A {
    public static final i = 10;
    public abstract int getNumber( );
}

  子类必须覆写全部抽象方法(子类要实现全部的抽象方法)

abstract class Father {
    private int money;    

    public int getMoney() {return money; }
    public void setMoney(int money) {this.money = money; }

    public abstract void study();
}

interface A {
    public static final int i = 10;//将public static final删除,其还是等效于有public static final,且i不能被修改(i是全局常量)
    public abstract int getNum();//将public abstract删除,其也等效于有public abstract
}

interface B {
    public static String name = "InterfaceB";
    public abstract String getName();
}

class Son extends Father implements A,B{//子类不仅可以继承父类(只能继承一个父类),还可以实现多个接口
    public int getNum() {return i;}//子类必须覆写全部抽象方法(子类要实现全部的抽象方法),在{}中写i++;会编译出错,因为i是全局常量
    public String getName() {return name;}
    public void study() {System.out.println("I am study"); }    
}

public class Ext7 {
    public static void main (String args[]) {
        Son son = new Son();
        System.out.println(son.getName());
        son.study();
    }
}