面对对象的三大特性: 3、多态

多态

动态编译类型 - 同一方法能够根据发送对象的不一样而采用多种不一样的行为方式。java

一个对象的实际类型是肯定的,但能够指向对象的引用的类型有不少。ide

多态存在的条件

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象

注意:多态是方法的多态,属性没有多态性oop

instanceof测试

一个对象的实际类型是肯定的code

new Student();对象

new Person();继承

可是,能够指向的引用类型就不肯定了编译器

子类重写了父类的方法,就执行子类的方法io

多态注意事项

  1. 多态是方法的多态,属性没法多态
  2. 父类和子类,有联系,类型转换异常! ClassCastException!
  3. 存在条件: 有继承关系,若有须要方法须要重写,父类引用指向子类对象! Father f1 = new Son();

没法被重写的方法(修饰符):编译

  • static 静态方法 - 方法,属于类,而不属于实例

  • final 常量

  • private 私有方法也不能被重写

被这三个修饰符修饰的方法没法被重写,因此也没法实现多态

若是没有“重写Override”,不能重复方法/方法名

  1. 父类Person
package oop.Demo06;

public class Person {
    public void run(){
        System.out.println("run");
    }
}
  1. 子类Student
package oop.Demo06;

public class Student extends Person {

    //重写在父类Person的run方法,今后父类子类都执行此处的方法
    @Override
    public void run() {
        System.out.println("son");
    }

    //父类Person没有这个方法-eat,所以在测试里,父类Person没法调用此方法
    public void eat(){
        System.out.println("eat");
    }
}
  1. 测试Application
package oop;

import oop.Demo05.A;
import oop.Demo05.B;
import oop.Demo06.Person;
import oop.Demo06.Student;

public class Application {
    public static void main(String[] args) {

        //一个对象的实际类型是肯定的
        //new Student();
        //new Person(); new Person/Student后就是new Person/Student
        //可是,能够指向的引用类型就不肯定了: 父亲的引用指向子类
        // 也就是 y与x, 多个x能够获得相同的y值

        //子类"Student"能执行的方法都是本身的或是继承父类的!
        Student s1 = new Student(); // 子类指向的引用
        //父类Person能够指向子类"Student",可是不能够调用子类独有的方法
        Person s2 = new Student(); // 父类指向的引用
        Object s3 = new Student(); //由于Person是student的父类,Object是默认的父类因此,能够newStudent以这三种形式
        //对象能执行那些方法,主要看对象左边的类型(父类、子类),和右边关系不大

        s2.run(); // 父类Person
        //s2.eat(); 没法调用
        s1.run(); //Student 类
        s1.eat();//子类能够调用本身的方法eat

        //输出结果为
        //son
        //son
        //都变成了son,经历过Override, 子类重写了父类的方法,就执行子类的方法
    }
}

1613629876

instanceof 关键词

instanceof (类型转换)

经过instanceof能够判断一个对象是什么类型

经过instanceof能够判断两个类之间是否存在父子关系

总结为公式:
System.out.println(x instanceof y); 编译器可否经过取决于x与y是否有父子类关系

怎么使用instanceof判断类与类之间的关系:

package oop;

import oop.Demo05.A;
import oop.Demo05.B;
import oop.Demo06.Person;
import oop.Demo06.Student;
import oop.Demo06.Teacher;

public class Application {
    public static void main(String[] args) {
        //Object > Person > Student//Teacher
        //Object > Person > Teacher
        //Object > String

        Object object = new Student(); //Object是Person的父类,Person是"Student"的父类
        //使用new在object和 Student 创建了这种关系,那么使用instanceof验证一下
        System.out.println(object instanceof Student); // True
        System.out.println(object instanceof Person); // True
        System.out.println(object instanceof Object); // True
        System.out.println(object instanceof Teacher); // False
        System.out.println(object instanceof String); // False

        System.out.println("========================");
        Person person = new Student();
        System.out.println(person instanceof Student); // True
        System.out.println(person instanceof Person); // True
        System.out.println(person instanceof Object); // True
        System.out.println(person instanceof Teacher); // False
        //System.out.println(person instanceof String); // False Person和String是平行关系,同级关系 !!编译器报错!!


        System.out.println("========================");
        Student student = new Student();
        System.out.println(student instanceof Student); // True
        System.out.println(student instanceof Person); // True
        System.out.println(student instanceof Object); // True
        //System.out.println(student instanceof Teacher); // False Student和Teacher是同级关系 !!编译器报错!!
        //System.out.println(student instanceof String); // False String和Student没有关系     !!编译器报错!!

        // 总结为公式:
        //System.out.println(x instanceof y); 编译器可否经过取决于x与y是否有父子类关系
    }
}

类型之间的转换

  1. 基本类型转换
  • 高-低 64 32 16 8
    • 高转低会有溢出,低转高不要紧
  1. “类”型之间的转换
  • 父子之间的转换: 低转高没问题,高转低须要强制转换
  • 父类引用指向子类的对象
  • 子类转换为父类, 向上转型,无需强制转换
  • 父类转换为子类,向下转型,须要强制转换,子类可能会丢失本身的方法
  • 可是父类转换为子类,便利与方法的调用,减小重复的代码!

低转高是慢慢长大,高转低是返老还童,会失忆

//高                     低
Person student = new Student(); //子类Student这个对象被new成父类Person, 低转高 OK
//student.go();
//可是此时,student没法使用"Student"de方法go

//student[父类Person]将这个对象转换为Student[子类Student],我么就可使用"Student"类型的方法了
Student student1 = (Student) student; //高转低, Person student -- Student student1 强制转换
((Student) student).go(); //通过强制转换就可使用 更低一层-子类 的方法了

//子类转换为父类,可能会丢失一些本身的方法

/*
栗子:
Object example = new Student(); //低转高
Student example2 = (Student) example; //
((Student) example).go();
 */
相关文章
相关标签/搜索