多态和特殊类

来自拉钩教育-JAVA就业集训营

多态的概念

  • 多态主要指同一种事务表现出来的多种形态。
  • 饮料:可乐、雪碧、红牛、脉动、……
  • 宠物:猫、狗、鸟、小强、鱼……

多态的语法格式

  • 父类类型 引用变量名 = new 子类类型();
    • 如:
    • Shape sr = new Rect();
    • sr.show();

多态的特点

  • 当父类类型的引用指向子类类型的对象时,父类类型的引用可以直接调用父类独有的方法。
Shape s2 = new Rect(7, 8, 9, 10);
int ia = s2.getX(); // 父类独有的方法
System.out.println("获取到的横坐标:" + ia);
  • 当父类类型的引用指向子类类型的对象时,父类类型的引用不可以直接调用子类独有的方法。
  • 对于父子类都有的非静态方法来说,编译阶段调用父类版本,运行阶段调用子类重写的版本(动态绑定)。
  • 对于父子类都有的静态方法来说,编译和运行阶段都调用父类版本。

引用数据类型之间的转换

  • 引用数据类型之间的转换方式有两种:自动类型转换和强制类型转换。
Shape s2 = new Rect(7, 8, 9, 10);
// s2 的类型是 Rect的父类
((Rect)s2).getLen();
  • 自动类型转换主要指小类型向大类型的转换,也就是子类转换为父类,也叫作向上转型。
  • 强制类型转换主要指大类型向小类型的转换,也就是父类转为子类,也叫做向下转型或显示类型转换。
  • 引用数据类型之间的转换必须发生在父子类之间,否则编译报错。
  • 若强转的目标类型并不是该引用真正指向的数据类型时则编译通过,运行阶段发生类型转换异常。
  • 为了避免上述错误的发生,应该在强转之前进行判断,格式如下:
    • if (引用变量 instanceof 数据类型)
    • 判断引用变量指向的对象是否为后面的数据类型

多态的实际意义

  • 多态的实际意义在于屏蔽不同子类的差异性实现通用的编程带来不同的效果。

抽象方法的概念

  • 抽象方法主要指不能具体实现的方法并且使用abstract关键字修饰,也就是没有方法体。
  • 具体格式如下:
    • 访问权限 abstract 返回值类型 方法名(形参列表);
    • public abstract void cty();

抽象类的概念

  • 抽象类主要指不能具体实例化的类并且使用 abstract 关键字修饰,也就是不能创建对象。

抽象类和抽象方法的关系

  • 抽象类中可以有成员变量、构造方法、成员方法;
  • 抽象类中可以没有抽象方法,也可以有抽象方法;
  • 拥有抽象方法的类必须是抽象类,因此真正意义上的抽象类应该是具有抽象方法并且使用 abstract 关键字修饰的类。

抽象类的实际意义

  • 抽象类的实际意义不在于创建对象而在于被继承。
  • 当一个类继承抽象类后必须重写抽象方法,否则该类也变成抽象类,也就是抽象类对子类具有强制性和规范性,因此叫做模板设计模式。

开发经验分享

  • 在以后的开发中推荐使用多态的格式,此时父类类型引用直接调用的所有方法一定是父类中拥有的方法,若以后更换子类时,只需要将 new 关键字后面的子类类型修改而其他地方无需改变就可以立即生效,从而提高了代码的可维护性和可扩展性。
  • 该方式的缺点就是:父类引用不能直接调用子类独有的方法,若调用则需要强制类型转换。

抽象类的应用

  • 银行有 定期账户和活期账户。继承自 账户类。账户类中:

  • public class Account {
    private double money;
    public double getLixi(){}
    }

  • private 和 abstract 关键字不能共同修饰一个方法 private限制方法为私有,abstract修饰的方法必须被重写

  • final 和 abstract 关键字不能共同修饰一个方法 final限制方法不能被重写,abstract修饰的方法必须被重写

  • static 和 abstract 关键字不能共同修饰一个方法 static 修饰的方法可以用 classname. 的方式访问, 抽象类不可以 用new 也就是static把方法提升到class层级,如果可以用 违背了 不能 new 对象。

接口的基本概念

  • 接口就是一种比抽象类还抽象的类,体现在所有方法都为抽象方法。
  • 定义类的关键字是class,而定义接口的关键字是 interface。
package com.lagou.task09;

public interface InterfaceTest {
    /*public static final*/ int CNT = 1; // 里面只能有常量
//    private void show(){} // 从jdk1.9尅是允许接口中出现私有方法
    /*public abstract*/ void show(); // 里面只能有抽象方法(新特性除外),注释中的关键字可以省略,但建议写上
}
  • 如:
    • 金属接口 货币接口 黄金类
package com.lagou.task09;

public interface Metal {
    // 自定义抽象方法描述发光的行为
    public abstract void shine();
}
package com.lagou.task09;

public interface Money {
    // 自定义抽象方法描述购物的行为
    public abstract void buy();
}
package com.lagou.task09;

// 使用 implements关键字表达实现的关系,支持多实现
public class Gold implements Metal, Money{
    @Override
    public void shine() {
        System.out.println("发出了金黄色的光芒……");
    }

    @Override
    public void buy() {
        System.out.println("买了好多好吃的……");
    }

    public static void main(String[] args) {
        // 1.接口类型的引用指向实现类的对象,形成了多态
        Metal mt = new Gold();
        mt.shine();

        Money mn = new Gold();
        mn.buy();
    }
}

接口和接口之间的关系练习

  • 题目
    • 编程实现Runner接口,提供一个描述奔跑行为的抽象方法。
    • 编程实现Hunter接口继承Runner接口,并提供一个描述捕猎行为的抽象法法
    • 编程实现Man类实现Hunter接口并重写抽象法法,在main方法中使用多态方式测试。
package com.lagou.task09;

public interface Runner {
    // 自定义抽象方法描述奔跑的行为
    public abstract void run();
}
package com.lagou.task09;

// 接口只能继承接口,不能继承类
public interface Hunter extends Runner {
    // 自定义成员方法描述捕猎的行为
    public abstract void hunt();
}
package com.lagou.task09;

public class Man implements Hunter {
    @Override
    public void hunt() {
        System.out.println("正在追赶一只小白如……");
    }

    @Override
    public void run() {
        System.out.println("正在被一只大熊追赶,玩命奔跑……");
    }

    public static void main(String[] args) {
        // 1.声明接口类型的引用指向实现类的对象,形成了多态
        Runner runner = new Man();
        runner.run();

        Hunter hunter = new Man();
        hunter.hunt();
    }
}

类和接口之间的关系

接口和抽象类的主要区别

  • 定义抽象类的关键字是 abstract class,而定义接口的关键字是 interface。
  • 继承抽象类的关键字是 extends,而实现接口的关键字是 implements。
  • 继承抽象类支持单继承,而实现接口支持多实现。
  • 抽象类中可以有构造方法,而接口中不可以有构造方法。
  • 抽象类中可以有成员变量,而接口中只可以有常量。
  • 抽象类中可以有成员方法,而接口中只可以有抽象方法。
  • 抽象类中增加方法时子类可以不用重写,而接口中增加方法时实现类需要重写(Java8以前的版本)。
  • 从Java8开始增加新特性,接口中允许出现非抽象方法和静态方法,但非抽象方法需要使用 default 关键字修饰。
    • public default void show1(){}
    • public static void test(){}
  • 从Java9开始增加新特性,接口中允许出现私有方法。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容