java面向对象三个特征之——多态

面向对象的第三特征:多态

1.什么是多态
    作为java三大特征之一的多态,顾名思义,就是同一事物在不同条件下下表现的状态,那不同的条件是什么呢? 比如说: 狗是动物的一种,狗的实例对象:旺财,他是狗的一种,也是动物的一种。用专业术语来说就是:作为狗的对象旺财,既可以调用狗类的属性、方法,也可以调用动物类的某些属性、方法

2.多态存在的3个必要条件
    ①要存在继承关系(包括接口的实现)(前提条件
    ②子类重写父类的方法(前提条件
    ③父类的引用指向子类的对象
        格式:父类类名 变量名 = new子类类();

特点一:();在使用多态后的对象调用父类的方法时,会调用子类重写过的方法
     代码演示:

public  class demo5 {//父类
    public void eat(){
        System.out.println("猫会吃a");
    }
}

class demo5b extends demo5{
    //子类b重写父类的方法
    public void eat(){
        System.out.println("狗会吃b");
    }
}

class demo5c extends demo5{
    //子类c重写父类的方法
    public void eat(){
        System.out.println("猫会吃c");
    }
}

class Test{//测试类
    public static void main(String[] args) {
        demo5 d5 = new demo5b();
        //父类的引用指向子类b的对象
        d5.eat();

        d5 = new demo5c();
        d5.eat();

        //方法的形式参数类型是父类类型,而传递的实际参数可以是任意子类的对象
    }
}

     那么输出结果显而易见,多态后的对象调用父类方法时会调用子类重写的方法在这里插入图片描述
特点二: 多态的 静态方法、成员变量 满足 :编译运行都看左边;
               多态的 成员方法 满足:编译看左边,运行看右边

    代码演示(编译运行看左边)//FU text = new ZI();:

package TextDemo;

public class FU {
    String name = "旺财";//成员变量
    static public void m1(){//静态方法
        System.out.println("父类静态方法m1");
    }
}
class ZI extends FU{
    String name1 = "小黑";//子类成员方法

    static public void m1(){
        System.out.println("子类静态方法m2");
    }

}
class Text{//测试类
    public static void main(String[] args) {
        //多态
        FU text = new ZI();//父类引用指向子类的对象
        /**
         * 调用成员变量、静态方法,
         *   编译和运行都看左边
         *   左边是父类,所以调用父类的成员变量与静态方法
         */
        System.out.println(text.name);
        text.m1();//静态方法也可以用对象名调用,但是不建议这样做。

        /**
         * 输出结果:
         *   旺财
         *   父类静态方法m1
         */
    }
}

(编译看左边,运行看右边)//FU text = new ZI();

public class FU {
    public void m3(){
        System.out.println("父类成员方法m3");
    }
}
class ZI extends FU{
    public void m3(){
        System.out.println("子类成员方法m3");
    }

}
class Text{//测试类
    public static void main(String[] args) {
        //多态
        FU text = new ZI();//父类引用指向子类的对象
        /**
         * 调用成员方法,
         *   编译看左边,运行右边
         *   看起来是父类的方法,但实际运行的却是子类的方法
         */
        text.m3();
        
        /**
         * 输出结果:
         *   子类成员方法m3
         */
    }
}

特点三: 多态的转型和instanceof关键字
    使用多态,提高了程序的扩展性,这是它的优点。那么有优点必然也会有缺点。多态最直接的缺点就是无法继承子类独有的方法因为编译是看左边,左边是父类的引用,用父类的引用来调子类独有的成员方法,编译器就是报错。那有没有解决的方法?
    转型就是一个很好的解决方法。转型,顾名思义:从一个类型的变量转换到另一个类型的变量,这很好理解,就好比基本数据类型的转型:

        int a =10;
        short b = (short) a;
        long c = a;

    这也符合小转大,随便转;大转小,要强转的法则。将对子类的对父类的对象可以默认转换,但是将父类的对象装换位子类的对象要强制转换,所以,之前的多态,也就是父类的引用指向子类的对象,都是默认的向上转型。那什么是向下转型呢?

        子类类型 变量名=(子类类型) 父类类型的变量;

    在配合instanceof(判断对象是否是某个数据类型//返回值是布尔值) 就可以完美的实现多态,技能调用父类属性,也能调用子类独有属性。

最后以作业的形式来完成多态:
        编写一个Person抽象类,要求含有姓名(name)年龄(age)两个私有属性以及吃饭(eat) 和睡觉(sleep)两个抽象方法,并写出带参构造方法,创建学生(student)和工人(worker) 两个类,继承Person类,学生类多出了私有属性学号和学习方法(输出我爱学习),工人类多出了私有属性工号和工作方法(输出我爱工作),在主函数中创建学生和工人类 的实例对象,使用构造方法赋值,并输出所有属性和方法

public class demo2 {
    public static void main(String[] args) {
        //编译看左边,运行看右边
        //学生类:
        Person student = new Students();

        //设置、输出名字
        student.setName("张三");
        System.out.println("名字是"+student.getName());
        //设置、输出年龄
        student.setAge(19);
        System.out.println(student.getAge()+"岁");
        //设置、输出学号
        //先向下转型,在调用子类的方法
        Students students = (Students) student;
        students.setNum("1110001010");
        students.getNum();

        //父类的两个方法
        student.eat();
        student.sleep();
        //独立的方法
        students.study();
        System.out.println("——————————————");

        //工人类:
        Person work = new Worker();

        //设置、输出名字
        work.setName("李四");
        System.out.println("名字是"+work.getName());
        //设置、输出年龄
        work.setAge(19);
        System.out.println(work.getAge()+"岁");
        //设置、输出学号
        //先向下转型,在调用子类的方法
        Worker worker = (Worker) work;
        worker.setNum2("0001110011");
        worker.getNum2();

        //父类的两个方法
        work.eat();
        work.sleep();
        //独立的方法
        worker.work();
    }
}
abstract class Person{
    private String name;
    private int age;

    public Person(String number){
        System.out.println("Person带参构造方法");
    }
    public Person(){//无参构造方法

    }
    public abstract void eat();
    public abstract void sleep();
    
    //get、set私有属性
    public void setAge(int age){
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

class Students extends Person{//子类:学生类
    //省略了super();
    public void eat(){
        System.out.println(getName()+"学生吃");
    }
    public void sleep(){
        System.out.println(getName()+"学生睡觉");
    }
    //私有属性方法
    private String num;
    public void study(){
        System.out.println("我爱学习");
    }
    
    //get、set私有属性
    public void setNum(String num){
        this.num = num;
    }
    public String getNum(){
        return num;
    }
}

class Worker extends Person{//子类:工人类
    public void eat(){
        System.out.println(getName()+"工人吃饭");
    }
    public void sleep(){
        System.out.println(getName()+"工人睡觉");
    }

    //私有属性和工作方法
    private String num2;
    public void work(){
        System.out.println("我爱工作");
    }

    //get、set私有属性
    public void setNum2(String num2){
        this.num2 = num2;
    }
    public String getNum2(){
        return num2;
    }
}
/**
 * 输出:
 * 名字是张三
 * 19岁
 * 张三学生吃
 * 张三学生睡觉
 * 我爱学习
 * ——————————————
 * 名字是李四
 * 19岁
 * 李四工人吃饭
 * 李四工人睡觉
 * 我爱工作
 */

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值