zoukankan      html  css  js  c++  java
  • java基础14 多态(及关键字:instanceof)

    面向对象的三大特征:  

    1.封装   (将一类属性封装起来,并提供set()和get()方法给其他对象设置和获取值。或者是将一个运算方法封装起来,其他对象需要此种做运算时,给此对象调用)

    2.继承   (继承关系通过extends关键字体现)

    3.多态   (父类的引用指向子类的对象,或者接口的引用类型变量指向接口实现类的对象)


    1、多态的含义

        父类的引用指向子类的对象,或者接口的引用类型变量指向接口实现类的对象

    2、多态的应用

        1.多态应用于形式参数的时候,可以接收更多类型的数据.
        2.多态用于返回值时,可以返回更多类型的数据.

    3、多态的好处

        提高了代码的拓展性.

    4、多态的弊端

        虽然提高了扩展性,但是只能使用父类引用指向父类成员。

    5、多态的前提

        类与类之间有关系,继承或者实现

    6、多态体现

        1:父类引用变量指向了子类的对象
        2:父类引用也可以接受自己的子类对象

    7、类型转换场景的问题

    java.lang.ClassCaseException.类型转换失败  

    8、附录

    如果需要访问子类特有的成员,那么需要进行强制类型转换
    
    1、基本数据类型转换:
      小数据类型------>大数据类型    自动转换
      大数据类型------>转小数据类型   强制类型转换   
    
    2、引用类型转换:
      小数据类型------->大数据类型    自动转换
      大数据类型------->转小数据类型    强制类型转换

    9、实现关系下的多态

    接口的引用类型变量指向接口实现类的对象
    格式: 接口 变量
    = new 接口实现类的对象

    例子:

     1 interface Dao {  //接口的方法全部都是非静态的方法
     2     public void add();
     3     public void delete();
     4 }
     5 
     6 //接口的实现类
     7 class UserDao implements Dao{
     8     public void add(){
     9         System.out.println("添加员工!!!");
    10     }
    11     public void delete(){
    12         System.out.println("删除员工");
    13     }
    14 }
    15 
    16 class Demo2 {
    17     public static void main(String[] args) {
    18         //实现关系下的多态
    19         Dao d=new UserDao(); //接口的引用类型变量指向接口的实现类的对象
    20         d.add();
    21         d.delete();
    22     }
    23 }

    10、实例

    例子1:

    /*
        1:Father类
            1:非静态成员变量x
            2:静态成员变量y
            3:非静态方法eat,方法体输出父类信息
            4:静态方法speak();方法体输出父类信息    
        2:Son类
            1:非静态成员变量x
            2:静态成员变量y
            3:非静态方法eat,方法体输出子类信息
            4:静态方法speak();方法体输出子类信息
    */
    class Father {
        int x = 1;
        static int y = 2;
    
        void eat() {
            System.out.println("开吃");
        }
        static void speak() {
            System.out.println("小头爸爸");
        }
    }
    
    class Son extends Father {
        int x = 3;
        static int y = 4;
    
        void eat() {
            System.out.println("大头儿子很能吃");
        }
        static void speak() {
            System.out.println("大头儿子。");
        }
    }
    
    class Demo10 {
        public static void main(String[] args) {
            Father f = new Son(); // 父类引用指向了子类对象。
            System.out.println(f.x); //返回结果:1
            System.out.println(f.y); //返回结果:2
    
            f.eat(); // 输出的是子类的方法
            f.speak(); // 输出的是父类的方法
        }
    }

    解析:子类(Son)继承父类(Father

    1:创建Father f=new Son();
    1:这就是父类引用指向了子类对象。
    2:问f.x=?(非静态)
    3:问f.y=?(静态)
    4:问f.eat()输出的是子类还是父类信息?(非静态)
    5:问f.speak()输出的是子类还是父类信息?(静态)

    总结:

    1:当父类和子类具有相同的非静态成员变量,那么在多态下访问的是父类的成员变量
    2:当父类和子类具有相同的静态成员变量,那么在多态下访问的是父类的静态成员变量     所以:父类和子类有相同的成员变量,多态下访问的都是父类的成员变量。
    3:当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类的成员方法。
    4:当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法。

    例子2:

     1 //动物类
     2 abstract class Animal{
     3     String name;
     4     public Animal(String name){
     5         this.name=name;
     6     }
     7 
     8     public abstract void run(); //抽象方法
     9 }
    10 //老鼠类
    11 class Mouse extends Animal{
    12     public Mouse(String name){ //调用父类构造器,目的:获取成员变量name中的值
    13         super(name);
    14     }
    15     public void run(){ //重写父类的抽象方法
    16         System.out.println(name+"四条腿慢慢走");
    17     }
    18 
    19     public void dig(){//Mouse子类特有的方法
    20         System.out.println(name+"老打洞...");
    21 
    22     }
    23 }
    24 //鱼类
    25 class Fish extends Animal{
    26     public Fish(String name){
    27         super(name);
    28     }
    29     public void run(){ //重写父类的抽象方法
    30         System.out.println(name+"摇着尾巴游啊游...");
    31     }
    32     public void bubble(){ //Fish子类特有的方法
    33         System.out.println(name+"吹泡泡....");
    34     }
    35 }
    36 
    37 class Demo6 {
    38     public static void main(String[] args) {
    39         Animal a=new Mouse("米老鼠");//多态,父类的引用指向子类的对象
    40         a.run();
    41         //a.dig(); //报错
    42         
    43         Mouse m=(Mouse)a;//强制类型转换  
    44         m.dig(); //如果直接用a.dig()的话,会报错,因为是多态(父类中没有dig()方法),所以要强制转换类型
    45 
    46         Animal a1=new Fish("金枪鱼");
    47         Fish f=(Fish)a1;
    48         print(f);
    49     }
    50 
    51     //需求,定义一个函数可以接收任意类型的动物对象,在函数的内部要调用到动物特有的方法
    52     //instanceof
    53     public static void print(Animal a){//Animal a=new Fish();
    54         if(a instanceof Fish){
    55              Fish f=(Fish)a;
    56              f.bubble();
    57         }else if(a instanceof Mouse){
    58             Mouse m=(Mouse)a;
    59             m.dig();
    60         }else{
    61             System.out.println("输入错误");
    62         }
    63     }
    64 }

    例子3:instanceof关键字(在末尾)

     1 //形状类
     2 abstract class MyShape{//抽象类
     3     public abstract void getLength(); //抽象方法
     4     public abstract void getArea(); //抽象方法
     5 }
     6 //圆形
     7 class Circle extends MyShape{
     8     public final static double PI=3.14; //常量
     9     double r;
    10     public Circle(double r){
    11         this.r=r;
    12     }
    13 
    14     public void getLength(){
    15         System.out.println("这是圆形的周长"+2*PI*r);
    16     }
    17     public void getArea(){
    18         System.out.println("这是圆形的面积"+PI*r*r);
    19     
    20     }
    21 }
    22 //矩形
    23 class Rect extends MyShape{
    24     int width;
    25     int height;
    26 
    27     public Rect(int width,int height){
    28         this.width=width;
    29         this.height=height;
    30     }
    31     public void getLength(){
    32         System.out.println("这是矩形的周长"+2*(width+height));
    33     }
    34     public void getArea(){
    35         System.out.println("这是矩形的面积"+width*height);
    36     }
    37     public void t(){
    38         System.out.println("来咬我啊!!!");
    39     }
    40 }
    41 
    42 class Demo5 {
    43     public static void main(String[] args) {    
    44 MyShape mp=new Circle(3.0);//多态,父类的引用指向了子类的对象 45 mp.getLength(); 46 mp.getArea();
    47     //方法2
    48     Circle c = new Circle(3.0);
    49 Rect r = new Rect(5,8); 50 MyShape m = new Rect(8,3); 51 //m.t(); //报错,此处需要强制类型转换 52 print(r); 53 print(c);//new Circle(3.0) 54 } 55 56 //需求1.定义一个函数可以接收任意类型的对象,并且打印图形的面积与周长 57 public static void print(MyShape s){//相当于:MyShape s=new Circle(3.0) 58 s.getLength(); 59 s.getArea(); 60 MyShape m = getShape(1); 61 } 62 63 //需求2:定义一个函数可以返回任意类型的图形对象. 64 public static MyShape getShape(int i){ 65 66 if(i == 1){ 67 return new Circle(2.0); 68 }else if(i == 0){ 69 return new Rect(6,9); 70 }else{ 71 return null; 72 } 73 } 74 }

    原创作者:DSHORE

    作者主页:http://www.cnblogs.com/dshore123/

    原文出自:http://www.cnblogs.com/dshore123/p/8891998.html

    欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!

  • 相关阅读:
    [设计模式]暂时不考虑多线程的单例模式
    [设计模式]策略模式
    [设计模式]工厂模式
    [设计模式]观察者模式1(用JDK提供的API)
    使用visual studio 2013 快速搭建phonegap开发环境
    js日期计算及快速获取周、月、季度起止日
    HTTP 错误 500.21
    C# 实现对网站数据的采集和抓取
    js设置控件的隐藏与显示的两种方法
    jQuery操作checkbox选择
  • 原文地址:https://www.cnblogs.com/dshore123/p/8891998.html
Copyright © 2011-2022 走看看