一、 概述

多态是继封装、继承之后,面向对象的第三大特性,指同一行为,具有多个不同表现形式。生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也是不一样的。可见,同一行为,

通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。

多态体现的格式:父类类型 变量名 = new 子类对象;变量名.方法名();

    代码如下:
Fu f = new Zi();
f.method();

1.1  多态调用成员方法

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后的方法(编译看左边,运行看右边)。

1.2  多态调用成员变量

当使用多态方式调用成员变量时,首先检查父类中是否有该变量,如果没有,则编译错误;如果有,执行的是父类的成员变量(编译看左边,运行看左边)。

1.3  多态的类型转换

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子类特有的方法,必须做向下转型。

代码如下:

abstract class Animal {
abstract void eat();
} class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
} public void catchMouse() {
System.out.println("抓老鼠");
}
} class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
} public void watchHouse() {
System.out.println("看家");
}
} public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// 向下转型
Cat c = (Cat) a;
c.catchMouse(); // 调用的是 Cat 的 catchMouse
}
}

但是,转型有可能会发生异常,请看下面代码

public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// 向下转型
Dog d = (Dog)a;
d.watchHouse(); // 调用的是 Dog 的 watchHouse 【运行报错】
}
}     
    这段代码可以通过编译,但是运行时,却报出了 ClassCastException ,类型转换异常!这是因为,明明创建了Cat类型对象,运行时,当然不能转换成Dog对象的。这两个类型并没有任何继承关系,不符合类型转换的定义。为了避免ClassCastException的发生,Java提供了 instanceof 关键字,给引用变量做类型的校验,格式如下:
  • 变量名 instanceof 数据类型
  • 如果变量属于该数据类型,返回true。
  • 如果变量不属于该数据类型,返回false。
    所以,转换前,我们最好先做一个判断,代码如下:
public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// 向下转型
if (a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse(); // 调用的是 Cat 的 catchMouse
} else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHouse(); // 调用的是 Dog 的 watchHouse
}
}
}

二、  final关键字

final: 不可改变。可以用于修饰类、方法和变量。

  • 类:被修饰的类,不能被继承。
  • 方法:被修饰的方法,不能被重写。
  • 变量:被修饰的变量,不能被重新赋值(如果修饰的是引用类型变量,不可修改其指向地址,但是可以修改引用类型的属性值)。

三、  权限修饰符

    在Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,
  • public:公共的。
  • protected:受保护的
  • default:默认的
  • private:私有的

3.1  不同权限的访问能力

四、  内部类

4.1  概述

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。内部类可以直接访问外部类的成员,包括私有成员。外部类要访问内部类的成员,必须要建立内部类的对象。

4.2  匿名内部类 

    匿名内部类 是内部类的简化写法。它的本质是一个带具体实现的父类或者父接口的匿名的子类对象。开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,
  • 1. 定义子类
  • 2. 重写接口中的方法
  • 3. 创建子类对象
  • 4. 调用重写后的方法
    而我们的目的,最终只是为了调用方法,那么能不能简化一下,把以上四步合成一步呢?匿名内部类就是这样做的快捷方式。代码如下
 //定义接口:
public abstract class FlyAble {
public abstract void fly();
} public class InnerDemo {
public static void main(String[] args) {
       /*1.等号右边:是匿名内部类,定义并创建该接口的子类对象 2.等号左边:是多态赋值,接口类型引用指向子类对象 */
FlyAble f = new FlyAble() {
public void fly() {
System.out.println("我飞了~~~");
}
};
//调用 fly方法,执行重写后的方法
f.fly();
}
}
    通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。代码如下: 
public class InnerDemo3 {
  public static void main (String[]args){
  /*创建匿名内部类,直接传递给showFly(FlyAble f) */
showFly(new FlyAble() {
public void fly() {
System.out.println("我飞了~~~");
}
});
}
public static void showFly (FlyAble f){
f.fly();
}
}

摘自:黑马程序员讲义

JavaSE基础知识之多态的更多相关文章

  1. JavaSE基础知识总结

    最近回顾了一下Java的基础知识,决定写成博客梳理一遍,主要是JavaSE部分最基础的知识,适合考前突击,学后回顾,不适合作为初学材料. 简单的列个目录吧: 一.数据类型和运算符 二.流程控制与数组 ...

  2. JavaSE 基础知识(常识概念 + 基础语法)问答总结/面试题 —— 讲给应届生的 Java 开源知识项目

    写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...

  3. JavaSE基础知识(5)—面向对象(5.4面向对象三大特征:封装、继承、多态)

    面向对象编程具有三大特征: 封装 继承 多态 一.封装 1.好处 狭义的封装:也就是属性的封装,避免了任意赋值的危险,提高了数据的安全性! ①隐藏一个类中不需要对外提供的实现细节 ②使用者只能通过实现 ...

  4. javaSE基础知识(走向编程的门口)— 更新完毕

    前言:玩儿编程最重要的一点:不要怕麻烦,感觉是在浪费时间: 能动手绝不哔哔:只要脑袋不傻,编程都是"一看就会,一练就废",开始学的时候,就算再基础的东西都建议手敲一遍 要有囫囵吞枣 ...

  5. JAVA核心技术I---JAVA基础知识(多态)

    一:类转型 类转型:子类可以转父类,父类不可以转子类(除非父类对象本身就是子类) 1.父类 public class Human { public void say() { System.out.pr ...

  6. Java基础知识总结--多态

    面向对象编程的三大特性:封装.继承.多态 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据,而外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承是 ...

  7. JavaSE基础知识(3)—流程控制结构

    一.顺序结构 1.说明 程序从上往下依次执行,中间没有任何跳转或选择2.特点 变量必须遵循 “前向引用” (局部变量必须先声明.赋值,然后再使用!) 二.分支结构(条件) 1.说明 程序从两条或多条路 ...

  8. JavaSE基础知识(2)—变量和运算符

    一.变量 1.理解 概念:内存中的一块数据存储空间 2.变量的三要素 数据类型变量名变量值 3.变量的语法和使用步骤★ 步骤1:声明变量(计算机开辟一块空间) 数据类型 变量名;步骤2:为变量赋值(初 ...

  9. JavaSE基础知识(1)—初识Java

    一.JAVA的背景 JAVA本身隶属的公司的是sun公司(创始公司) JAVA创始人:詹姆斯 高斯林 09年被oracle收购 JAVA的前身是Oak 二.JAVA的版本 95年 JAVA诞生96年 ...

随机推荐

  1. postgreSQL计算总数sum if case when

    假设postgreSQL中表名为user,现在需要计算每个用户参加过的次数(is_join字段为null时不算,表中的null并不是字符串''或者字符串'Null' ,而是数据库中的null类型) u ...

  2. 使用arcpy.mapping 更新和修复数据源

    来自:https://blog.csdn.net/gisinfo/article/details/6675390 在许多情况下,您都可能需要修复数据源或重定向数据源至其他位置.然而,如果是在每个相关的 ...

  3. 【8583】ISO8583各域段的说明

    [ISO8583各域段的说明] 1,信息类型(message type)定义位图位置:-格式:定长类型:N4描述:数据包的第一部分,定义数据包的类型.数据类型由数据包的发起者设定,应遵循以下要求:数据 ...

  4. 用SQL语句操作Sqlite数据库的示例代码

    import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.databa ...

  5. Scala语法04 - 其他

  6. kettle在linux下面用于shell脚本执行:转换或者作业

    1 将windows下面创建好的转换,放到Linux某一个文件夹下面.如:把0816_em.ktr文件放到/home/cfj/kettle/testdemo下面. 注意里面的数据库用户名和密码可能需要 ...

  7. Java集合(6):理解Map

    映射表的基本思想是维护键-值对的关联,通过键来寻找值.下面是标准Java类库中几种Map的实现: (1) HashMap:Map基于散列表的实现,插入和查询键值对的开销是固定的.可以通过构造器设置容量 ...

  8. SqlServer:SqlServer(服务器磁盘监控,创建管理员账号分配权,添加链接服务器,查询CPU,查询内存)

    1.服务器磁盘监控 (1)总链接服务上开启所有链接服务器的RPC: ----------------------总链接服务器上面,开启每个服务器的RPC --exec sp_serveroption ...

  9. 20190903 - CSDN 的奇葩替换

    可能是出于安全原因 CSDN 对内容中的代码,作了很多奇葩的替换. 比如下面两行,是否有差别? # - # -16 有.其实 cut 后的短横线,内部编码不同,前者复制后无法被识别. 再比如下面两个词 ...

  10. 【CodeForces - 598D】Igor In the Museum(bfs)

    Igor In the Museum Descriptions 给你一个n*m的方格图表示一个博物馆的分布图.每个方格上用'*'表示墙,用'.'表示空位.每一个空格和相邻的墙之间都有一幅画.(相邻指的 ...