ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java基础笔记(十八)——多态

2019-03-11 20:43:36  阅读:169  来源: 互联网

标签:Java 子类 多态 笔记 Cat Animal 父类 方法 public


多态表示同一个操作作用在不同对象时,会有不同的结果。

多态可分为编译时多态和运行时多态。

编译时多态:方法重载,编译时就可以确定到底调用哪个方法,可以被看做一个类中的方法多态性。

运行时多态:只有在运行时才能确定调用哪个方法,方法重写实现的多态是运行时多态。子类可以重写父类的方法,因此同样的方法在父类与子类有不同的表现形式。有两个必要条件:

-满足继承关系

-父类引用指向子类对象(向上转型、隐式转型、自动转型     小 -> 大)  Animal one=new Cat();   或者Animal one=new Cat();  Cat cat=new Cat();   two=cat;   

多态的表现

Java中,父类的引用变量不仅可以指向自己的类型的实例对象,也可以指向其子类的实例对象。程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。这种动态绑定的方法实现了多态。

父类类型创建子类对象,该对象可以调用父类派生的方法,子类重写的方法,但不能使用子类独有的方法。

public class Base {
    public Base(){
        g();
    }
    public void f(){
        System.out.println("Base f()");
    }
    public void g(){
        System.out.println("Base g()");
    }
}

public class Derived extends Base {
    public void f(){    //重写了父类的f()
        System.out.println("Derived f()");
    }
    public void g(){   //重写了父类的g()
        System.out.println("Derived g()");
    }
    public void d(){     //子类独有的方法
        System.out.println("d()");
    }
}

public class Test {
    public static void main(String[] args){
        Base b=new Derived();   //调用父类构造函数,由于多态性,会调用子类重写的g()方法
        b.f();   //调用子类重写的f()方法
        //b.d();   编译报错,由于子类对象为父类引用指向,不能调用自己独有的方法
    }
}

 

子类引用指向父类对象(向下转型、强制类型转换),与向上转型相比,它可以调用子类特有的方法,但必须满足转换条件。

Animal  one =new Cat();     //对象one是自动转为Animal类型,但是Cat类的实例

Cat temp=one;  //编译报错 ,需强制类型

Cat temp=(Cat)one;

Dog temp2=(Dog)one;   //编译报错,不满足转换条件,父类类型指向的实例化对象,只能强转换回对象对应的类型。

instanceof运算符

对象instanceof类,返回true/false,判断它左边的对象是否是它右边的类的实例,也就是判断对象是否满足某个特定类型实例特征,该运算符返回boolean类型的数据。

这样在进行向下强转类型时,就可以用instanceof来判断是否可以进行强转。

public class Test {
    public static void main(String[] args){
        Animal one =new Cat();
        //Cat和Dog都继承Animal类
        if(one instanceof Cat){   //常放在类型强转前
            Cat temp=(Cat)one;   //满足强转条件
            System.out.println("one可以转换为Cat类型");
        }
        if(one instanceof Dog){
            Dog temp=(Dog)one;
            System.out.println("one可以转换为Dog类型");
        }
        if(one instanceof Animal){     //Animal是实例one的父类,所以one具有Animal特征
            System.out.println("Animal");
        }
        if(one instanceof Object){  //Object是Animal的父类,所以one具有Object的特征
            System.out.println("Object");
        }
    }
}

//运行结果
one可以转换为Cat类型
Animal
Object

 之前方法重写说,返回值类型要相同,返回值为父类类型的时候,在方法重写时是可以向下兼容的,但不能向上兼容,例如下例,方法重写返回为子类类型是可以的,但是Object不行。

父类

public Animal create(){ return new Animal();}

子类

@Override

public Dog create(){ return new Dog();}

 

static修饰的类方法,属于类共享,只能被继承,不能被重写。即使在子类出现同名的方法,也是子类独有的方法。

父类中的静态方法无法被子类重写,所以向上转型之后,只能调用到父类原有的静态方法。如果想调用子类自己的独有的静态方法,需要类型再转回来。

Animal one=new Cat();  one.say();  //调用父类静态方法

Cat two=(Cat)one;     two.say();   //调用自己的独有的静态方法

如果有一个饲养员类,去喂养不同的动物,每个动物的特征行为又不同。编写方法,传入不同类型的动物对象,调用各自的方法。

public void feed(Cat cat){

        cat.eat();      //重写父类方法

        cat.playBall();    //独有方法

}

public void feed(Dog dog){

        dog.eat();      //重写父类方法

        dog.sleep();    //独有方法

}

那如果有好多动物,要写一堆动物及他们各自的独有方法,有点儿麻烦。

也可以这样实现:

传入动物的父类,方法中通过类型转换,调用指定子类的方法。

public void feed(Animal obj){

      if(obj instanceof Cat){

              Cat temp=(Cat)obj;

    temp.eat();   //如果只有这个吃的方法就不需要类型判断,强制转换了,因为可以直接调用重写父类的方法

    temp.playBall();   //子类自己独有的方法,只能强制转换回自己的类型,否则作为父类类型不能直接调用子类独有的方法

  }else if(obj instanceof Dog){

    Dog temp=(Dog)obj;

    temp.eat();

    temp.sleep();

  }

}

第二种比第一种编码效率会高,但如果再新增其它类的话,要在这个方法里面进行修改,会破坏已有方法的封装性。

 

只有类中的方法才有多态的概念,类中成员变量没有多态的概念。成员变量是无法实现多态的,成员变量的值取决父类还是子类并不取决于创建对象的类型,而是取决于所定义变量的类型,这是在编译期间确定的。

class Base{

  public int i=1;

}

class Derived extends Base{

  public int i=2;

}

public class Test{

  public static void main(String[] args){

    Base b=new Derived();

    System.out.println(b.i);

  }

}

运行结果:1

标签:Java,子类,多态,笔记,Cat,Animal,父类,方法,public
来源: https://www.cnblogs.com/tendo/p/10511520.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有