自学内容网 自学内容网

继承与多态 Java

目录

1.继承

1.1 继承概念

1.2 继承的语法

1.3 父类成员访问

1.3.1 子类中访问父类的成员变量

1.3.2 子类中访问父类的成员方法

1.4 super关键字

1.5 子类构造方法

1.6 super和this

1.7 再谈初始化

1.8 protected关键字

1.9 继承方式

1.10 final关键字

1.11 继承与组合

2. 多态

2.1 多态的概念

2.2 多态实现条件

2.3 向上转型

2.4 方法的重写

2.5 向下转型

2.6 多态的优缺点

2.7 避免在构造方法中调用重写的方法


1.继承

1.1 继承概念

继承机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。继承主要解决的问题是:类的共性的抽取,实现代码复用。

1.2 继承的语法

在Java中如果要表示类之间的继承关系,需要借助extends关键字,例如:

package demo1;

public class Dog extends Animal{
    public void bark(){
        System.out.println(this.name+"正在叫");
    }
}

注意:

  1. 子类会将父类中的成员变量或者成员方法继承到子类中
  2. 子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则没必要继承
1.3 父类成员访问
1.3.1 子类中访问父类的成员变量

子类和父类存在同名变量的时候,优先访问子类的!(就近原则)

如果要访问父类的a,需要super关键字:

System.out.println("父类的a:"+super.a);

也可以实例化一个对象:

        Base base = new Base();
        System.out.println("父类的b:" + base.b);
1.3.2 子类中访问父类的成员方法

注意:

  1. 通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
  2. 通过派生类对象访问父类与子类中同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法时传递的参数选择合适的方法访问,如果没有则报错

super和this都可以通过.来访问成员变量和成员方法,通过()来访问构造方法

1.4 super关键字

该关键字主要作用:在子类方法中访问父类的成员

注意:只能在非静态方法中使用

使用super调用构造方法时,只能放在第一行,this()也必须在第一行,所以,this()和super()不能共存

1.5 子类构造方法

子类对象构造时,需要先调用基类的构造方法,然后执行子类的构造方法(先父后子)

当没有提供任何的构造方法的时候,Java中会提供目前屏蔽起来的代码

class AA {
    /*public AA(){

    }*/
}

class BB extends AA {
   /* public BB(){
        super();
    }*/
}

但是只要写了任何一个构造方法,都不会自动提供。

public class Derived Base{
    public Derived(){
        //super();子类构造方法中默认会调用基类的无参构造方法
        //用户没有写时,编译器会自动添加,而且super();必须是子类构造方法中第一条语句
        //并且只能出现一次
    }
}
1.6 super和this

相同点:

  1. 都是Java中的关键字
  2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
  3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

不同点:

  1. this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象从父类继承下来部分成员的引用
  2. 在构造方法中,this(...)用于调用本类构造方法,super(...)用于调用父类构造方法,两种调用不能同时在构造方法中出现
  3. 构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...)用户不写则没有
1.7 再谈初始化
package demo3;

public class Animal {
    String name;
    int age;
    static {
        System.out.println("static Animal");
    }
    {
        System.out.println("实例代码块Animal{ }");
    }
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
        System.out.println("Animal()");
    }
}
package demo3;

public class Dog extends Animal{
    static {
        System.out.println("static Dog");
    }
    {
        System.out.println("实例代码块 Dog{ }");
    }
    public Dog(String name,int age){
        super(name,age);
        System.out.println("Dog()");
    }
}
package demo3;

public class Cat extends Animal{
    static{
        System.out.println("static Cat");
    }
    {
        System.out.println("实例代码块 Cat{ }");
    }
    public Cat(String name,int age){
        super(name,age);
        System.out.println("Cat()");
    }
}

 创建一个对象,先执行父类和子类的静态,再执行父类的实例和构造,最后执行子类的实例和构造。

创建两个对象,先执行一次父类和子类的静态,再执行对象一的父类和子类的实例和构造,最后执行对象二的父类和子类的实例和构造。

1.8 protected关键字

private只能在当前类使用(同一包同一类)

default同一个包下的类可以访问

public公开的,哪里都可以使用

protected在同一个包下可以使用,不同包的只有子类可以使用,非子类无法访问。

1.9 继承方式

Java不支持多继承,一个类只能继承一个父类

但是可以通过接口的形式支持多继承

一般不希望出现超过三层的继承关系,如果继承次数太多,就需要考虑对代码进行重构了。

1.10 final关键字

如果一个类不想被其他类继承,可以使用关键字final来修饰这个类,此时这个类叫做密封类。

如果使用final修饰变量,这个变量将不能被修改。

1.11 继承与组合

和继承类似,组合也是一种表达类之间的关系的方式,也能够达到代码重用的效果,组合并没有涉及到特殊的语法(诸如extends这样的关键字),仅仅是将一个类的实例作为另一个类的字段。

继承表示对象之间是is-a的关系,组合表示对象之间是has-a的关系

public Student[] students=new Student[10];

2. 多态

2.1 多态的概念

通俗来讲,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生不同的状态。

2.2 多态实现条件

再Java中要实现多态,必须满足以下几个条件,缺一不可:

  1. 必须在继承体系下
  2. 子类必须要对父类中方法进行重写
  3. 通过父类的引用调用重写的方法

多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法

2.3 向上转型

子类——>父类(向上转型)

1.直接赋值:

public class Test {
    public static void main(String[] args) {
        /*Dog dog=new Dog("旺财",10);
        Animal animal=dog;*/
        Animal animal=new Dog("旺财",10);
    }
}

2.方法的传参

public class Test {
    public static void func(Animal animal){
        
    }
    public static void main(String[] args) {
        Dog dog=new Dog("旺财",10);
        func(dog);
    }
}

3.返回值

    public static Animal func(){
        Dog dog=new Dog("旺财",10);
        return dog;
    }

向上转型的优点:让代码实现更加简单灵活

向上转型的缺点:不能调用到子类特有的方法

2.4 方法的重写
  1. 方法的名字一样
  2. 参数列表一样【顺序、个数、类型】
  3. 返回值一样

当运行代码的时候,调用了父类和子类重写的那个方法,结果实际上调用了子类的方法,这种情况叫做动态绑定

父类引用子类对象,并且通过父类引用调用了父类和子类重写的那个对象。

注意:

  1. 不能是一个静态方法
  2. 不能是被final修饰的方法【密封方法】
  3. 子类重写父类的方法,那么子类的权限≥父类的权限
  4. 被private修饰的方法不能被重写
  5. 被重写的方法返回值可以不同,但必须具有父子关系

对于已经投入使用的类,尽量不要进行修改,最好的方法是:重新定义一个新的类,来重复利用其中共性的内容,并且添加或者改动新的内容。(重写)

静态绑定:也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用哪个方法,典型代表函数重载。

动态绑定:也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用哪个类的方法。

2.5 向下转型
    public static void main(String[] args) {
        Aniaml animal=new Bird("小鸟",2);
        Bird bird=(Bird)animal;//强制类型转换
        bird.fly();
    }

向下转型有风险,不是所有的向下转型都是可以成功的。万一转型失败,运行时就会抛出异常。Java中为了提高向下转型的安全性,引入了instanceof,如果表达式为true,则可以安全转换。

2.6 多态的优缺点

使用多态的好处:

1.能够降低代码的“圈复杂度”,避免使用大量的if-else

一段代码中条件语句和循环语句出现的个数称为“圈复杂度”,如果一个方法的圈复杂度太高,需要考虑重构

2.可扩展能力强

对于类的调用者来说,只要创建一个新类的实例即可,改动成本低

多态缺陷:

代码运行效率低。

1.属性没有多态性。当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性。

2.构造方法没有多态性

2.7 避免在构造方法中调用重写的方法

如果在父类的构造方法中调用子类和父类重写的方法,此时会发生动态绑定。


原文地址:https://blog.csdn.net/2301_80802299/article/details/140477127

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!