java提供了一个关键字extends,用这个关键字,可以使一个类与另一个类建立父子关系。

public class B extens A{

}

A类称为父类或者基类,B类称为子类或者派生类。

继承的特点:子类能继承父类的非私有成员(成员变量、成员方法)

继承后对象的创建:子类的对象是由子类、父类共同完成的。

public class A {
    
    public int i;
    public void print1(){
        System.out.println("===A1===");
    }
    private int j;
    private void print2(){
        System.out.println("===A2===");
    }
}  // 2.定义一个类变量记住类的一个对象
public class B extends A {
    public int k;//可以在test包下使用,因为B是A的子类
    private int n;//不能被test调用
   public void print3() {

       System.out.println(i);
       print1();
       //print2();//报错
   }
}
public  class test {

    public static void main(String[] args) {
        B b = new B();
        System.out.println(b.i);
        System.out.println(b.k);
        //System.out.println(b.n);报错
        
        b.print2();//报错
        b.print1();
        b.print3();

    }

}

使用继承可以减少重复代码的编写。

关于继承的注意事项:

(1)权限修饰符

面向对象高级之二 继承_父类

其中,缺省和protected很少用。

 (2)Java是单继承的,Java中的类不支持多继承,但是支持多层继承。

   object类是所以类的祖先,生成的类默认是object的子类

(3)当子类局的父类中的某个方法不好用,或者无法满足自己的需求,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的方法。重写后,方法的访问,Java会遵循就近原则。

B继承A,A的方法不好,可以在B重新写,但是名字和格式要一样,再调用时就会调用B的方法。

重写时要加上@ Override 可以帮助检查有没有错误。

@Override

public void print2(){

System.out.println("1");

}

(4)子类重写父类方法时,访问权限要大于或等于父类的方法权限。public

(5)重写的方法,返回值类型要一样,或者更小,更小的问题以后再说。

(6)私有方法静态方法不能被重写,会报错。

(7)如果输出一个变量的内容时,输出的不是地址而是内容,说明他的tospring被重写了。

(8)这是就近原则。

public class A {

    String name = "lzk3";
    public void print1() {
        System.out.println("111");
    }

}


public class B extends A {
   String name  = "lzk1";
   public void printName(){

      String name = "lzk2";
      System.out.println(name);//lzk2

      System.out.println(this.name);//lzk1
      System.out.println(super.name);//lzk3,super是父类的引用
   }
}
public  class test {

    public static void main(String[] args) {
        B b = new B();
        b.printName();
    }
}

对于方法的调用也可以使用super

(9)子类构造器:子类的全部构造器,都会先调用父类的构造器,再执行自己。

class F{
    public F(){
        System.out.println("F的无参构造器被执行");
    }
}
class Z extends F{

    public Z(){
        System.out.println("Z的无参构造器被执行");
}
    public Z(String name){
        System.out.println("Z的有参构造器被执行");
    }
}


public  class test {

    public static void main(String[] args) {
        Z z = new Z();
        Z z1 = new Z("张三");
    }
}

执行结果:这是因为子类的无参或者有参构造器的第一行默认都会有一个super();来调用父类的无参构造器。如果父类没有无参构造器,那么必须再子类构造器的第一行手写super(),指定去调用父类的有参构造器。

面向对象高级之二 继承_System_02

(10)为什么子类构造器要调用父类构造器,有什么应用场景?

public class test1 {
    public static void main(String[] args) {
        Teacher t = new Teacher("Tom", 30, "Math");
        System.out.println(t.getName() + " is " + t.getAge() + " years old and teaches " + t.getSkill());

    }
}

class Teacher extends People{
    private String skill;
    public Teacher(String name, int age, String skill){
        super(name, age);//调用父类的构造函数
        this.skill = skill;//初始化自己的属性

    }
    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}
class People{
    private String name;
    private int age;

    public People(){

    }

    public People(String name, int age){//构造函数
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

补充知识:this()可以调用兄弟构造器

public class test1 {
    public static void main(String[] args) {
        Student s1 = new Student("Tom", 18, "xxx");
        System.out.println(s1.getName() + " " + s1.getAge() + " " + s1.getSchoolName());

    }
}
class Student{
    private String name;
    private int age;
    private String SchoolName;

    public Student(String name, int age) {
//        this.name = name;
//        this.age = age;
//        SchoolName = "uuu";//默认值,当没有传入SchoolName时,使用默认值
        this(name, age, "uuu");//使用带参数的构造器,这一行代码和上面的注释掉的两行代码等价,他调用的是下面Student(String name, int age, String schoolName)的构造器
    }
    public Student() {
    }
    public Student(String name, int age, String schoolName) {
        this.name = name;
        this.age = age;
        SchoolName = schoolName;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSchoolName() {
        return SchoolName;
    }

    public void setSchoolName(String schoolName) {
        SchoolName = schoolName;
    }
}

小知识,this和super不能同时出现,因为这两个都要在第一行,而且调用的也不一样,会起冲突。