JavaSE——继承和多态详解

简介: JavaSE——继承和多态详解

文章目录

一、继承

  1. 如何理解继承?
  2. 继承的语法
  3. 子类如何访问父类中的成员
  1. 子类构造方法
  2. final 关键字
  3. 继承与组合

二、多态

1.认识多态

 2. 多态实现条件

  1. 重写

4. 向上转移和向下转型

一、继承

  1. 如何理解继承?
  1. 继承的语法

关键字:extends

格式:

修饰符 class 子类 extends 父类 {

//... 

}
子类会继承父类的成员变量或者成员方法

子类继承父类后要添加自己特有的成员,即除了父类之外的特性

class Animal{

public String name;
public int age;

public void eat() {
    System.out.println(name+"吃饭");
}

}
class Dog extends Animal{

//新加的属性
public String silly;
public void houseGuard() {
    System.out.println("看门");
}

}
class Cat extends Animal {

//没有添加新属性
public void catchMouse()  {
    System.out.println(name+"抓老鼠");
}

}
public class Test {

public static void main(String[] args) {

    //name和age属性是从父类Animal中继承下来的

    Dog dog = new Dog();
    Cat cat = new Cat();

}

}
还要注意:Java中不支持多继承,一个子类只能继承一个父类

  1. 子类如何访问父类中的成员

3.1 访问成员变量
成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找

如果找不到,则在父类继承下来的成员变量中寻找要访问的成员变量,找不到编译失败

3.2 访问成员方法
成员方法名字不同:

优先访问自己的,若没有,去访问从父类继承的

成员方法名字相同:

父类和子类同名方法的参数列表不同(重载),根据调用方法适传递的参数选择合适的方法访问,没有则报错

3.3 super关键字
用法:在子类方法中访问父类的成员

class Dog extends Animal{


public String silly;
public void houseGuard() {

    System.out.println(super.name+"看门");

}

}
 父类的name没有赋初值,因此是null ,这样就访问到了同名的父类的成员变量

 this.会有优先问自己的,没有则访问从父类中继承的

super.直接访问从父类中继承下来的,在子类方法中,如果想要明确访问父类中成员时,借助super关键字即可

注意:上文父类的普通成员方法、变量是指非静态成员方法、变量

  1. 子类构造方法

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

看代码:

class Animal{

public String name;
public int age;

//提供一个两个该参数的构造方法
public Animal(String name, int age) {
    this.name = name;
    this.age = age;
}

public void eat() {
    System.out.println(name+"吃饭");
}

}

//此处报错

class Dog extends Animal{


public String silly;
public void houseGuard() {
    System.out.println(super.name+"看门");
}

}

对象的初始化需要调用构造方法

添加了带有两个参数的构造器后,编译器不会提供无参的构造方法,因此出现错误

接下来我们看当提供了两个参数的构造方法时如何初始化:

class Dog extends Animal{


public String silly;
    public Dog(String name, int age, String silly) {

    //先初始化父类部分
        super(name, age);
        this.silly = silly;

    }

    public void houseGuard() {
    System.out.println(super.name+"看门");
}

}
super(name,age)会先调用父类的构造方法完成初始化

this.silly = silly会完成自己属性的初始化

  1. final 关键字
  2. 修饰变量或字段,表示常量
  3. 修饰类:表示此类不能被继承

String 字符串类, 就是用 final 修饰的, 不能被继承

  1. 修饰方法:表示该方法不能被重写
  2. 继承与组合

与继承相似,组合也是表示类之间关系的方式,能实现代码的复用

继承表示各种类抽象出来的共性,对象之间是is-a的关系

组合(Composition)体现的是整体与部分、拥有的关系,即has-a的关系

例如交通工具车的组合:

class Tire {

public void run() {
    System.out.println("轮胎转动");
}

}

class Light {

public void light() {
    System.out.println("灯亮");
}

}

public class Vehicle {

private Tire tire;
private Light light;

public Vehicle(Tire tire,Light light) {
    this.tire = tire;
    this.light = light;
}

public void operation() {
    light.light();
    tire.run();
}

public static void main(String[] args) {
    Tire tire = new Tire();
    Light light = new Light();
    Vehicle vehicle = new Vehicle(tire,light);
    //灯亮
    //轮胎转动
    vehicle.operation();
}

}
二、多态
1.认识多态
不同的对象在完成某个行为时会产生出不同的状态就叫多态

例如:手机支付时产生的多态

 2. 多态实现条件

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

例如:

class Animal{

public String name;
public int age;

public Animal(String name, int age) {
    this.name = name;
    this.age = age;
}

public void eat() {
    System.out.println(name+"吃饭");
}

}

class Dog extends Animal{


public String silly;

    public Dog(String name, int age, String silly) {
        super(name, age);
        this.silly = silly;
    }
    @Override
    public void eat() {
        System.out.println(name+"吃狗粮");
    }

    public void houseGuard() {
    System.out.println(super.name+"看门");
}

}
class Cat extends Animal {

public Cat(String name, int age) {
    super(name, age);
}

@Override
public void eat() {
    System.out.println(name+"吃猫粮");
}
//没有添加新属性
public void catchMouse()  {
    System.out.println(name+"抓老鼠");
}

}
public class Test {

public static void eat(Animal animal) {

    animal.eat;

}

public static void main(String[] args) {
    Dog dog = new Dog("dog",2,"silly");
    Cat cat = new Cat("cat",3);
    eat(dog);
    eat(cat);

}

}

 Test类中的eat方法参数为Animal,该方法内部并不知道,也不关注当前的a引用指向哪个实例,此时 a这个引用调用 eat方法可能会有多种不同的表现(和 a 引用的实例相关), 这种行为就称为多态

  1. 重写

概念:返回值和形参都不能改变,子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写

重写的好处在于子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法

4. 向上转移和向下转型
向上转型:创建一个子类对象,将其当成父类对象来使用
//语法格式:父类类型对象名 = new 子类类型()

Animal animal = new Cat("cat",2);

 使用:

方法一:直接赋值(子类对象赋值给父类对象)

public class Test {

public static void main(String[] args) {
    Dog dog = new Dog("dog",2,"silly");
    Animal animal = dog;
    Animal animal1 = dog;
    Animal animal2 = dog;
}

}
方法二:方法传参(形参为父类型引用,可以接收任意子类的对象)

public static void eat(Animal animal) {

    animal.eat;

}

方法三:方法返回(作返回值:返回任意子类对象)

public static Animal func(){

    return new Cat("dog",2);
}

向下转型:父类引用再还原为子类对象
public class Test {

public static void main(String[] args) {

    Animal animal = new Cat("haha",2);

    if(animal instanceof Cat){
        Cat cat = (Cat) animal;
        cat.catchMouse();
    }
}

}
为了提高向下转型的安全性,引入了instanceof,如果该表达式为true,则可以安全转换

相关文章
|
1月前
|
Java 编译器
java类和对象:继承、多态、接口、抽象类-1
java类和对象:继承、多态、接口、抽象类
14 0
|
1月前
|
Java 编译器
java类和对象:继承、多态、接口、抽象类-2
java类和对象:继承、多态、接口、抽象类
36 0
|
1月前
javaSE&多态
javaSE&多态
12 1
|
1月前
|
安全 Java
JavaSE&匿名对象 , 继承 , 抽象类
JavaSE&匿名对象 , 继承 , 抽象类
|
9月前
|
安全 Java
【JAVASE】多态 下
【JAVASE】多态
|
1月前
|
Java 编译器
JavaSE学习之--继承和多态(一)
JavaSE学习之--继承和多态
45 0
|
1月前
|
Java
JavaSE学习之--继承和多态(二)
JavaSE学习之--继承和多态(二)
52 0
|
1月前
|
Java 编译器
JavaSE学习之--继承和多态(三)
JavaSE学习之--继承和多态(三)
46 0
|
11月前
|
Java 程序员 编译器
【JavaSE】一起学继承
【JavaSE】一起学继承
|
6月前
|
安全 Java 程序员
JavaSE继承和多态
JavaSE继承和多态