【JAVA学习之路 | 基础篇】面相对象特征--多态性

1.对象的多态性

  • 多态性,是面相对象中最重要的概念.在java中的体现 : 对象的多态性 : 父类的引用指向子类的对象.
  • 格式 : (父类类型 : 指子类继承父类的类型,或者实现的接口类型) 父类类型 变量名 =子类对象.
  • 例 : Object o = new Person(),Object类型的变量o指向子类Person类型的对象.
  • 在Java中,子类的对象可以替代父类的对象使用.所以,一个引用类型变量可能指向多个不同类型(子类类型)的变量

2.多态性的应用场景

  • (虚方法的调用)在Java中,虚方法是在编译阶段不能确定方法的调用入口地址,在运行阶段才能确定的方法,即可能被重写的方法.Person p =new Man(),p.XXX().屏蔽了子类特有的属性和方法.
  • 用父类做方法的形参,是多态使用最多的场合.即使增加了子类,方法也无需改变,提高了扩展性,符合开闭原则.
  • public class InsatnceText {
        public static void main(String[] args) {
            InsatnceText t = new InsatnceText();
            t.method(new Person());
            t.method(new Student());
            t.method(new Graduate());
        }
        public void method(Person e) {
            e.getInfo();
    }
    
    输出结果:
    a person
    a person
    a student
    a person
    a student
    a graduate
    
    
    public class Person {
        public Person() {}
      
        public void getInfo() {
            System.out.println("a person");
        }
    }
    
    public class Graduate extends Person {
        public void getInfo() {
            System.out.println("a person");
            System.out.println("a student");
            System.out.println("a graduate");
        }
    }
    
    public class Student extends Person {
        public void getInfo() {
            System.out.println("a person");
            System.out.println("a student");
        }
    }

  • 在多态的场景下,调用方法时,(1).编译时,认为方法是左边声明的父类的类型的方法(即被重写的方法).(2).运行时,实际执行的是子类重写父类的方法.
  • 即编译看左边,运行看右边.

3.使用前提和适用性

(1).使用前提 : 要有类的继承关系 ; 要有方法的重写.

(2).适用性 : 适用于方法,不适用于属性.

4.多态的好处和弊端

(1).好处 : 极大的减少的代码的冗余,不需要定义多个重载的方法.如方法形参里带父类的类型变量,实参传子类的对象.

(2).弊端 : 在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法,但由于声明为父类的引用,导致我们没有办法直接调用子类特有的属性和方法.(但可以通过向下转型)

5.向上转型

(1). class Animal{

    public int i =1;

    public void eat() {

         System.out.println("Animal is.eating");

    }

}

class Person extends Animal{

    public int i =2;

    @Override

    public void eat() {

        System.out.println("Person is eating");

    }

    public void sleep() {

    System.out.println("Person is sleeping");

    }

}

class Cat extends Animal{

    public int i =3;

    @Override

    public void eat() {

        System.out.println("Cat is eating");

    }

}

  • Aminal a =new Person();    //父类的引用指向子类的对象.
  • p只能调用父类声明的方法,而该方法通常被子类重写,故运行时实际上调用的是子类重写的方法.
  • 由于编译类型为Animal,不能调用子类特有的方法,因为父类中并没有声明该方法,如果a.sleep(),编译器会报错.
  • 通过new创造对象时父类的属性和方法,子类的属性和方法均被加载到内存中,如果将输出a.i的值,将输出1.同时体现了,方法才有多态性,而属性没有.

6.向下转型

  • 如果我们确实需要调用子类特有的方法及属性,可以通过强制类型转换.
  • 如果将输出p.i的值,将输出2.

Person p =(Person) a;    //向下转型

此时编译类型为Person,可以调用子类特有的方法.p.sleep()  //true

7.instanceof关键字

(1). (对象A) instanceof (类名B)

(2). A是否是B的实例,如果是,则返回true;否则,IDEA将产生异常.(if A为null,不会产生异常,只是返回false)

(3). 举例

Animal a =new Animal();

Person p =new Person();

Cat c =new Cat();

  • a instanceof Object   //true
  • p instanceof Animal   //true  人是动物
  • c instanceof Animal   //true  cat是动物
  • c instanceof Person   //异常   cat不是人

  • 21
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值