多态

多态就是对象的多种形态,即相同的消息使得不同的类做出不同的响应。

多态存在的三个必要条件:继承、重写、父类变量引用子类对象(向上转型)。

实现多态的技术称为动态绑定,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载

对象和对象引用

new关键字

创建一个Java对象需要三部:声明引用变量、实例化、初始化对象实例。

①声明引用变量

声明一个变量来指向一个对象,即引用

要声明一个变量,需要写:Animal animal;

这将告诉编译器你将使用animal引用一个Animal类型的对象。用一个原始变量,这个声明也保留了适当的内存量的变量。

②实例化

new运算符实例化一个类对象,通过给这个对象分配内存并返回一个指向该内存的引用。

“实例化一个类的对象”的意思就是“创建对象”。创建对象时,你正在创造一个类的“实例”,因而“实例化”一个类的对象。

③初始化对象实例

就是调用构造方法,对类的实例数据赋初值。构造函数的名称提供了需要实例化类的名称。

对象

对象是类的一个实例,创建对象的过程也叫做类的实例化。

如人类是一个类,那么我们每一个具体的人就是这个类的对象。

对象引用

我们知道new关键字是一个java运算符,它用来创建对象

Animal animal;  //声明一个变量来指向一个对象,即引用

animal = new A animal();

如上代码,创建对象的语句是new Animal(),那么animal又是什么呢?animal只是一个引用,是指向一个对象的引用,这个对象指向Animal类。也就是说,Animal animal 这句话只是声明了一个Animal类的引用,它可以指向任何Animal类的实例。

一个引用可以指向多个对象,而一个对象也可以被多个引用所指。

引用多态

父类的引用可以指向本类的对象   Animal animal=new Animal();

父类的引用可以指向子类的对象  Animal animal=new Dog();

注意:父类的引用指向子类的对象时,子类中特有的方法和属性就不能使用了。

方法多态

创建本类对象时,调用的方法为本类方法

创建子类对象时,调用的方法为子类重写的方法或者继承的方法(不能为子类特有的)

类型转换

多态中的类型转换是基于存在继承关系的对象,有向上类型转换和向下类型转换。

向上转型:父类的引用可以指向子类的对象

如 Animal animal=new Dog();  //Animal类是Dog类的父类

Dog对象实例被向上转型成了animal,但Dog对象实例本质上还是Dog类型,只不过能力被暂时削弱了

向下转型:向上转型之后子类特有的方法和属性就不能被调用了,有时我们想用这些方法和属性,就需要将向上转型后的子类对象再转成子类,调用子类的方法

如 Dog dog=(Dog)animal;

animal的引用仍然是Animal类型,只不过功能增强了,然后交给dog引用

注:不能直接将父类对象强制转换为子类类型,只能将向上转型后的子类对象在此转为子类类型。

向上转型就好比把茶杯里的水往茶壶中倒,是安全的;向下转型就是把茶壶里的水往茶杯里倒,会存在风险,instanceof运算符就可以避免类型转换的安全问题了。

instanceof就是去判断向下转型的对象将要转换的类型是不是这个对象的类型

如:Animal animal = new Dog();//父类引用指向了子类的对象

       Dog dog = (Dog)animal;//将子类对象的引用类型转成子类,用一个子类类型的引用来接收

       Cat cat = (Cat)animal;//编译器不报错,但是animal是Dog类的对象,在运行时会报错,此时需要用instanceof去判断一下

instanceof运算符用法:左边的操作元是一个对象,右边是一个类。如果左边的对象是右边类的实例,该运算符运算的结果是true,否则是false

注意:一个类的实例包括本身的实例,以及所有直接或间接子类的实例

          instanceof左边对象的类型(注意是它引用的对象的类型,不是变量的类型)与右边必须是同种类或是继承关系

class Animal{ }

class Dog extends Animal{ }


public class Test {

   public static void main(String[] args) {

       Animal animal=new Dog(); //向上转型

       if(animal instanceof Dog){

           Dog dog=(Dog)animal; //向下转型

       }

       else

           System.out.println("不能转换");

   }

}


一个经典的例子

public class A {

    public String show(D obj) {

    return ("A and D");

    }

    public String show(A obj) {

    return ("A and A");

    }

}


public class B extends A{

    public String show(B obj){

        return ("B and B");

    }

    public String show(A obj){

        return ("B and A");

    }

}


public class C extends B{ }

public class D extends B{ }


public class Test {

    public static void main(String[] args) {

        A a1 = new A();

        A a2 = new B();

        B b = new B();

        C c = new C();

        D d = new D();

        System.out.println("1--" + a1.show(b));

        System.out.println("2--" + a1.show(c));

        System.out.println("3--" + a1.show(d));

        System.out.println("4--" + a2.show(b));

        System.out.println("5--" + a2.show(c));

        System.out.println("6--" + a2.show(d));

        System.out.println("7--" + b.show(b));

        System.out.println("8--" + b.show(c));

        System.out.println("9--" + b.show(d));

    }

}

运行结果:

1--A and A

2--A and A

3--A and D

4--B and A

5--B and A

6--A and D

7--B and B

8--B and B

9--A and D

抽象类和接口

1.抽象类

当父类只知道子类的方法而不知道子类的方法如何实现时可以将子类定义为抽象类,若多个类都有一个共同的方法,则可以将它抽象成一个抽象类

抽象方法是一种特殊的方法,它只有声明,没有具体的实现(即方法体),以分号结束

如:abstract void fun();

如果一个类含有抽象方法,那这个类就是抽象类

抽象类中可以有普通方法和抽象方法

抽象类和抽象方法前面必须都有abstract修饰,因为抽象类中没有具体实现的方法,所以抽象类不能被实例化,实例化的工作交由子类去完成,它只需要有一个引用即可

抽象类就是为了继承实现的,如果一个类继承了抽象类,那么子类必须实现父类的抽象方法,如果子类没有继承父类的抽象方法,那么子类就必须也定义为抽象类

抽象方法必须为public或protected,如果没有访问控制符的话,默认为public

如果子类也是一个抽象类的话,可以不用实现父类的抽象方法,如果子类不是一个抽象类的话,就必须实现父类的抽象方法

2.接口

一个类只能extends一个父类,但可以implements多个接口,java通过接口的概念来实现c++中的多继承。一个接口可以同时extends多个接口,却不能implements任何接口,因而,Java中的接口是支持多继承的。

接口是由全局常量和公共的抽象方法所组成。

接口是要被继承实现的,所以不能用private和protected修饰,一般用public

接口中可以含有变量和方法,但接口中的变量会被隐式的指定为public static final(并且只能是public static final),因为接口中的属性是常量。方法会被隐式的指定为public abstract(并且只能是public abstract),因为接口中所有的方法不能有具体的实现,即这些方法必须都为抽象方法

允许一个类遵循多个接口

如果一个非抽象类遵循了某个接口,则这个类必须实现接口中的所有方法,如果一个抽象类遵循了某个接口。则可以不实现该接口中的方法

3.抽象类和接口的区别

抽象类中可以有普通的方法,接口中只能有抽象方法

抽象类中的成员变量可以使各种类型的,而接口中必须是public static final型的

接口中不能含有静态代码块以及静态方法,抽象类中可以有

一个类只能继承一个抽象类,而一个类可以遵循多个接口

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容