package com.day11.inheritence;
/*
从现有类创建(衍生)子类,现有类称为父类,基类,超类
子类会继承父类的所有成员 构造器除外
子类继承父类的语法:class 子类extends 父类{}
子类继承父类私有成员时,父类必须提供公共的方法以间接的使用这些成员

方法覆盖(override):在子类中重写父类的方法,因为父类的方法不能满足需要;
覆盖条件
   1)父类中和子类中的方法的签名要完全一致,方法签名包括 返回值类型方法名(参数列表)一致,参数列表一致体现类型,个数,顺序都一致
   2)子类方法中的方法控制修饰符要大于等于父类的,如果父类方法时public,子类只能必须时public

super表示超级的意思,作用是特别指定后面的成员是从父类继承的
this表示当前对象,是一个整体
super只是一个标识,用于表示从父类继承的成员

创建子类时会调用到父类的构造器
 如果在子类构造器中什么也没有时,编译器会自动添加一个语句super();作用是直接调用父类的无参构造器
 如果已经右super(),编译器不做处理
        直接效果就是,子类的构造器一定会默认的调用父类的无参构造器

    super()语句必须是构造器中的第一行,目的保证了父类构造器必须先指向

    父类的无参构造器默认会被所有子类调用,所以在父类中提供无参构造器是非常重要其必须的
关于构造器
    1.子类构造中必须有--先对--父类构造器的调用!!!子类构造器第一行,只能是 super(...)或this(...)
      1)子类构造器中的第一行 可以是super(...),作用直接显式的调用父类构造器,如果子类构造器中是空的,默认添加super(...)
      2)子类构造器中的第一行 可以是this(...),作用是调用本类重载构造器,目的确实间接调用父类构造器
    2.所有类都必须要与构造器

    多态:子类对象的多种父类形态
    本态:子类对象的本类形态

    多态引用:子类对象赋值于父类类型的引用变量
    本态引用:子类对象赋值于本类类型的引用变量

    看右面 子类对象的多种父类形态
    看左面 父类类型的引用的多态性

    若编译时类型和运行时类型不一致,就出现多态(Polymorphism)
    编译时类型(左边)和运行时类型(右边)不一致时,就出现了多态

 */
public class Person {
    private String name;
    private int age;
    private String gender;

    public Person() {
        System.out.println("Person()");
    }

    public Person(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        System.out.println("Person(String,int,gender)3");
    }

    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 getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\''
                ;
    }
    public void sayHello(){//虚拟方法:唯一的作用就是骗过编译器
        System.out.println("hello");//不执行
    }
}
package com.day11.inheritence;

public class Chinese extends Person{
    String zodiac;
    //子类构造器第一行,只能是 super(...)或this(...)
    public Chinese() {
        //                                     如果在子类构造器中什么也没有时,编译器会自动添加一个语句super();作用是直接调用父类的无参构造器
        //super("张三",20,"男");//显式的直接调用了父类的有参构造器,如果有显式的调用,隐式调用不调。
        //zodiac = "未知";
        this("张三",20,"男","未知");
        System.out.println("Chinese()1");

    }
    //全参构造器


    public String getZodiac() {
        return zodiac;
    }

    public void setZodiac(String zodiac) {
        this.zodiac = zodiac;
    }

    public Chinese(String name, int age, String gender, String zodiac) {
        //子类中不可直接发访问父类继承来的私有成员
        super(name, age, gender);//直接显式的调用父类的全参构造器,借用父类构造器完成子类从父类继承的私有成员的初始化
        this.zodiac = zodiac;
        System.out.println("String name, int age, String gender, String zodiac2");
    }

    public void spring(){
        System.out.println(getName()+"想过年");//子类不可以直接访问父类继承的私有成员
                                                //子类必须通过从父类继承的公共的get/set方法间接方法从父类继承的私有成员
    }

    @Override//方法的覆盖(重写)子类的方法会覆盖父类的方法
    public String toString() {
        return super.toString()+",zodiac:"+zodiac;
    }
    @Override
    public void sayHello(){
        System.out.println("吃了吗");
    }
}
package com.day11.inheritence;

public class American extends Person {
    private boolean hasGun;

    public American() {
        System.out.println("American()");
    }

    public American(String name, int age, String gender, boolean hasGun) {
        super(name, age, gender);
        this.hasGun = hasGun;
    }

    public void christmas() {
        System.out.println("merry christmas");
    }

    public boolean isHasGun() {
        return hasGun;
    }


    public void setHasGun(boolean hasGun) {
        this.hasGun = hasGun;
    }

    @Override
    public String toString() {
        return super.toString()+"American{" +
                "hasGun=" + hasGun +
                '}';
    }
    @Override
    public void sayHello(){
        System.out.println("how ary you");
    }

}
package com.day11.inheritence;

import javax.swing.*;

public class PersonTest {
    public static void main(String[] args) {
        Chinese ch = new Chinese();
//        ch.setName("张三");
//        ch.setAge(29);
//        ch.setGender("男");
        ch.zodiac="虎";
        System.out.println(ch.getName());
        System.out.println(ch.getAge());
        System.out.println(ch.getGender());
        System.out.println(ch.zodiac);
        ch.spring();
        System.out.println(ch.toString());//执行时,执行的是子类的方法,因为父类的方法被覆盖了
        // System.out.println(ch.super.toString());在测试类中尝试再去使用被覆盖的方法,不允许


    }
}
package com.day11.inheritence;

public class PersonTest4 {
    public static void main(String[] args) {
        Person p = new Chinese();//只是把chinese看做是Person

        //p.spring();多态引用中子类特有的成员不可以访问。。多态副作用!

        //多态引用调用覆盖方法
        //虚拟方法调用(Virtual Method Invocation)
        //动态绑定:在运行时,究竟执行谁的方法时不确定,要取决于new的对象实体
        p.sayHello();//编译时检查父类类型,运行时执行子类类型

        p = new American(); //p引用指向的对象实体出现了不确定性
        p.sayHello();
    }
}

1. 子类继承了什么? 能继承父类的私有成员吗? 如何处理?

子类继承了父类的所有成员(变量,方法)

子类继承了父类的私有成员

         1)构造器的初始化;

         2)get/set(父类里的)

2. 为什么父类又叫基类或超类?

extends:子类 extends 父类

super:super;

3. 什么是方法覆盖? 方法覆盖有什么条件?

Override:如果子类中有一些需求是父类的方法直接拿过来没法用,满足不了

那么,子类就可以重写(Override)父类的方法

private(不行):修饰符(子类要大于等于父类的权限)

 返回值 方法名 (参数)完全一致

4. 如果A类被B类继承,B类又被C类继承, 在所有类中都有一个方法test(),

创建C类对象,调用test()方法,执行的是哪个类的方法? 在C类中有几个test()方法?

C类对象的test()

3个,A\B\C的test方法都有

从测试类角度来看C类, 只有一个test方法

从C类内部来看,有两个test方法, 一个是this.test(), 一个是super.test()

从继承的概念来看, 有3个

  1. 子类构造器中第一行有什么特别要求? 为什么?

要么super(可以有参数)要么this(可以有参数)

super(…) 作用是直接调用父类构造

this(…) 作用是间接调用父类构造.

如果是一个子类对象,调用super()来先初始化从父类继承的那部分成员;

this:本类下的其他构造方法;

结论 : 子类构造器中必须要有先对父类构造器的调用…

创建子类对象

  1. 检查继承体系中的所有类模板
  2. 如果没有, 加载时按先父后子的顺序加载类
  3. 如果有不加载
  4. 依据继承体系中的所有的类模板中属性的定义信息
  5. 全部写0
  6. 执行父类的显式赋值
  7. 执行父类构造器
  8. 执行子类显式赋值
  9. 执行子类构造器

访问权限修饰符

private 本类

default 本类 本包

protected 本类 本包 不同包子类

public 全局


多态:看右面,子类的对象的多种父类形态,看左面,父类类型的引用指向的多种不确定子类对象 把子类对象”看作是“父类对象来使用 本态:对象的本态形态 多态引用:子类对象赋值于父类类型的引用变量,父类类的引用指向子类对象 本态引用:子类对象赋值于父类类型的引用变量