day06 继承、多态

目录

1.继承

1.1什么是是继承

1.2继承的格式

1.3继承的核心优点

1.4继承的设计规范

1.5继承的内存原理

1.6继承的三大特点

1.7继承后变量与方法的访问特点

1.7.1遵循就近原则

1.7.2this关键字

1.7.3子类方法如何访问父类成员

1.8继承后方法重写

1.8.1概念

1.8.2重写后想调用父类方法怎么办

1.8.3@override

1.8.4重写的要求

1.9继承后子类构造器

1.9.1特点

1.9.2为什么

1.9.3代码层面

1.9.4继承后子类构造器访问父类有参构造器

2.多态

2.1什么是多态

2.2多态的使用前提

2.3多态的格式

2.4多态的调用方式

2.4.1调用方法

2.4.2调用变量

2.5多态的优势

2.6使用多态需要注意的问题

2.7多态的类型转换

2.7.1自动类型转换

2.7.2强制类型转换


1.继承

1.1什么是是继承

Java允许一个类通过extends与另一个类建立父子关系,这就是继承。

1.2继承的格式

子类 extends 父类

public class Consultant extends People{
    private int number;
}

1.3继承的核心优点

提高代码的复用性,多个子类的相同代码可以放在父类中,增强了类的扩展性。

1.4继承的设计规范

子类共用属性和行为放在父类,子类独有属性和行为放在子类自己那里。子类能继承父类的成员(成员变量、成员方法),但无法直接访问父类的私有成员

1.5继承的内存原理

子类对象实际上是由子父类这两张设计图共同创建出来的。

1.6继承的三大特点

【1】Java是单继承模式:一个类只能继承一个直接父类。

【2】Java不支持多继承、但是支持多层继承

public class Test01 {

    public static void main(String[] args) {
        ZI z = new ZI();

        System.out.println(z.zichan);
    }
}
//定义了父类
class XTBB{
}
class WSS{}
//1:Java中类的继承是单继承模式 一个类只能继承一个直接父类
// 不支持多继承
class DTEZ extends XTBB{}
//2:Java支持多层继承
class YE{
    String zichan="北京前门一套四合院";
}
class FU extends YE{}
class ZI extends FU{}

【3】Java中所有的类都是Object类的子类。

public class Test02 {
  // 所有的类直接或间接继承Object,Object定义的方法 所有的类都有!!
    public static void main(String[] args) {
         People people = new People();
         people.toString();//people 类中没有定义 toString()方法
        // 但是能够访问? 因为people 默认继承了Object 不写继承就是默认继承Object

        Student stu = new Student();
        stu.toString();// Student 类中没有定义 toString()方法
                       // People 类中没有定义 toString()方法
                       //原因是java支持多层继承 所以 Student 间接继承了Object
    }
}

class People{//不写继承 直接继承Object

}
class Student extends People{

}

1.7继承后变量与方法的访问特点

1.7.1遵循就近原则

先子类局部范围找,然后子类成员范围找,最后父类成员范围找,如果父类范围还没有找到则报错。

public class Test03 {

    public static void main(String[] args) {
        //目标 继承后 子类访问的特点  就近原则
        // this.  访问的本类的成员
        // super. 访问的父类的成员
        Z z = new Z();
        z.show();
    }
}

class F{
   String name = "父的Name";

    public void run(){
        System.out.println("父run");
    }
}
class Z extends F{
   String name = "子的Name";

    public void show(){
        String name = "show方法的name";
        System.out.println(name);//就近原则访问局部变量
        System.out.println(this.name);//就想访问 子类成员位置name怎么办
        System.out.println(super.name);//就想访问 父类成员位置name怎么办?

        this.run();//调用本类方法 但是this可以省略
        super.run();//调用父类方法
    }

    public void run(){
        System.out.println("子run");
    }
}

1.7.2this关键字

this.子类自己的成员变量

1.7.3子类方法如何访问父类成员

super.父类成员变量/父类成员方法

1.8继承后方法重写

1.8.1概念

当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写。

1.8.2重写后想调用父类方法怎么办

先使用super关键字调用父类同名方法,再继续编写子类独有的方法。

1.8.3@override

重写方法建议加上一个重写校验注解:@Override。要求必须是正确重写的才不报错。这样方法的可读性好。

public class OverrideTest {
    public static void main(String[] args) {
        Cat c = new Cat();
        c.load();
        c.sleep();
    }
}
class Animal{
    public void load(){
        System.out.println("动物都会叫");
    }
    public void sleep(){
        System.out.println("安详的睡");
    }
}
class Cat extends Animal{
    @Override //注解 表示当前这个方法 是重写的方法
    public void load() {
        System.out.println("喵~~喵~~~喵~~喵喵喵~");
    }
//    @Override 如果不是重写方法就报错
    public void play(){
        System.out.println("猫玩毛线~~");
    }
}

1.8.4重写的要求

【1】子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限( public > protected > 缺省 )。

【2】重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小

【3】私有方法、静态方法不能被重写,如果重写会报错的。

1.9继承后子类构造器

1.9.1特点

子类的全部构造器默认都会先访问父类的无参数构造器,再执行自己的构造器

1.9.2为什么

先有爸爸才有儿子。 先调用它爸爸的构造器初始化父类的数据,再调用自己的构造器初始化自己的数据。

1.9.3代码层面

默认子类构造器的第一行都有一个super(), 访问父类的无参数构造器,写不写都有

1.9.4继承后子类构造器访问父类有参构造器

super(...)调用父类有参数构造器,初始化继承自父类的数据。

/*
  在开发中的做法
     父类有属性
       那么我们就要生成父类的有参构造和无参构造
     子类
       需要写子类的无参构造  子类的有参构造

       子类有参构造
         参数
            自己类中属性需要的参数
            父类中属性需要的参数
         里面内容
            将父类构造需要的参数 传递父类有参构造--调用父类有参构造
            将子类自己需要参数 传递 自己的属性

 */
public class People {
    private String name;//外界无法访问
    private int age;
    //父类无参构造
    public People() {
        System.out.println("父类无参构造");
    }
    //父类有参构造
    public People(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("父类有参构造");
    }

    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 class Teacher extends People {
    private String skill;//技能
    //子类无参构造
    public Teacher() {
        System.out.println("子类的无参构造");
    }
    //子类有参构造 可以利用 快捷键
    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;
    }
}
public class Test {
    /*
      构造--创建对象的时候执行 用来完成成员变量的初始化!!!!
       字类构造器特点
           子类的全部构造,都会先调用父类的构造器,再执行自己的。
              默认语句是 super()表示调用父类的无参构造器
              如果父类没有无参构造,必须在子类构造器第一行手写super(...) 调用父类的指定的有参构造
     */
    public static void main(String[] args) {
        Teacher t= new Teacher("游戏仔",17,"原神启动,王者农药,斗地主");
        System.out.println(t.getName()+"---"+t.getAge()+"---"+t.getSkill());
    }
}

2.多态

2.1什么是多态

多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态。

//这是本态
Lv lv = new Lv();
//这是多态
Animal a = new Lv();

2.2多态的使用前提

【1】必须有继承或者实现关系

【2】父类类型的变量指向子类类型的对象

【3】存在方法重写

2.3多态的格式

父类类型 变量名称 = new 子类构造器;

Animal a = new Lv();

2.4多态的调用方式

2.4.1调用方法

编译看左边,运行看右边

2.4.2调用变量

编译看左边,运行也看左边(注意)

2.5多态的优势

【1】在多态形式下,右边对象是解耦合的,更便于扩展和维护。

【2】定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强、更便利。

2.6使用多态需要注意的问题

多态下不能直接访问子类独有功能

public class Animal {
    public void Load(){
        System.out.println("动物叫");
    }
}
public class Cat extends Animal{
    @Override
    public void Load(){
        System.out.println("我们一起学小卢");
    }

    public void playMaoXian(){
        System.out.println("玩得很开心");
    }
}
public class Lv extends Animal{
    @Override
    public void Load(){
        System.out.println("驴叫");
    }

    public void LaMo(){
        System.out.println("懒驴上磨屎尿多");
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal=new Lv();
//        animal.LaMo();报错,父类中没有LaMo方法
    }
}

2.7多态的类型转换

2.7.1自动类型转换

从子类到父类

2.7.2强制类型转换

【1】从父类到子类

【2】Java规定,有继承/实现关系的类就可以强制转换,编译阶段不会报错。但是运行时可能出现类型转换异常

【3】Java建议在进行强制转换之前先通过instanceof判断真实数据类型,再强转

【4】强转成子类对象后,就可以调用子类的独有功能了

public class Test02 {
    public static void main(String[] args) {
        Animal animal=new Cat();
        animal.Load();;
        if (animal instanceof Cat){
            Cat cat=(Cat) animal;
            cat.playMaoXian();
        }
    }
}

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值