类与接口(五)java多态、方法重写、隐藏
一、Java多态性
面向对象的三大特性:封装、继承、多态。
多态的类型,分为以下两种:
- 编译时多态: 指的是 方法重载。编译时多态是在编译时确定调用处选择那个重载方法,所以也叫 静态多态,算不上真正的多态。所以,一般说的多态都是运行时的多态。
- 运行时多态: 由于 方法重写,所以想要确定引用变量所调用的方法的入口,必须根据运行时的引用变量所指向的实例对象来确定。从而使得同一个引用变量调用同一个方法,但不同的实例对象表现出不同的行为。再简单点来说,就是在运行时,可以通过指向基类的指针,来调用实现子类中的方法。
下面讲的多态都是指 运行时的多态。
多态的定义: 指允许不同类的对象对同一消息做出不同的响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用);
上面的定义参考了网上的说法,定义中的不同类,都是由同一个基类扩展而来。
多态的好处:
- 可替换性(substitutability)。多态对已存在代码具有可替换性。例如,draw函数对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
- 可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
- 接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
- 灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
- 简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
java的多态性三要素:
- 继承;
- 重写;
- 父类的引用指向子类的引用
多态性的实现: 依靠动态绑定;
绑定: 将一个方法调用与方法主体关联起来。
前期绑定: 在程序执行前绑定,由编译器和链接程序完成,C语言的函数调用便是前期绑定。
动态绑定: 也称 后期绑定。在运行时,根据具体的对象类型进行方法调用绑定。除了static
方法、final
方法(private
方法也是final方法),其他方法都是动态绑定;
二、方法重写 与 隐藏
方法重写: 就是子类中覆盖了从父类继承下来的方法(不是所有的父类方法都可以覆盖),从而使得通过父类的引用来调用重写后的方法。也就是说,父类类型与子类类型只保留重写后的方法。
隐藏: 覆盖是相对重写而言的。当子类中出现与父类相同的方法时,重写是子类与父类只保持一份,但方法隐藏则是子类与父类各自独立保持一份,也就两份。从父类继承下来的成员中,除了部分方法是可以重写外,其余成员都是隐藏,如变量、内部类、静态方法等。
注意: final方法既不能重写,也不能隐藏。
class ParentClass{public int a = 5;protected final String name = "parentClass";public final void finalMethod() {//final方法,子类既不能重写,也不能隐藏System.out.println("final方法");}public static void monday() {//静态方法System.out.println("父类ParentClass的monday()方法");}public void count() {//可继承的成员方法System.out.println("父类ParentClass的count()方法");}class InnerClass{//内部类public InnerClass() {System.out.println("父类ParentClass的内部类");}}
}class ChildClass extends ParentClass{public int a = 5;protected final String name = "ChildClass";/*//编译不通过* public final void finalMethod() {System.out.println("final方法");}*/public static void monday() {//静态方法System.out.println("子类ChildClass的monday()方法");}public void count() {//可继承的成员方法System.out.println("子类ChildClass的count()方法");}class InnerClass{//内部类public InnerClass() {System.out.println("子类ChildClass的内部类");}}
}public class MyTest {public static void main(String[] args) {ChildClass child = new ChildClass2();ParentClass parent = child; //类型上转System.out.println("---------------变量的隐藏测试-----------------");child.a = 10;System.out.println("parent.a: "+parent.a);System.out.println("child.a: "+child.a);System.out.println("\n---------------静态方法的隐藏测试-----------------");parent.monday();child.monday();System.out.println("\n---------------方法的重写测试-----------------");parent.count();child.count();System.out.println("\n---------------内部类的隐藏测试-----------------");ParentClass.InnerClass pa = parent.new InnerClass();ChildClass.InnerClass ch = child.new InnerClass();}
}
—————变量的隐藏测试—————–
parent.a: 5
child.a: 10
—————静态方法的隐藏测试—————–
父类ParentClass的monday()方法
子类ChildClass的monday()方法
—————方法的重写测试—————–
子类ChildClass的count()方法
子类ChildClass的count()方法
————–内部类的隐藏测试—————–
父类ParentClass的内部类
子类ChildClass的内部类
上面的例子中,只有count()
方法是被重写了,父类类型与子类类型只保持重写后的方法,而其他成员都是隐藏,父类类型保持一份,子类类型也保持一份。
方法重写的条件
- 重写的方法是子类从父类继承下来的实例方法,不能是静态方法
- 子类重写后的方法的 返回类型 必须是 原父类方法的返回类型的可替换类型
- 子类重写后的方法的访问权限 不能比 原父类方法的访问权限低;
- 子类重写后的方不能比父类方法抛出更多的异常;
- 当重写泛型方法时,先进行类型擦除。再按照上面的4个小点,重写类型擦除后的方法;
可替换类型补充:
- 对于返回类型是基本类型、void,重写方法的返回类型必须是一样;
- 对于返回类型是引用类型,返回类型可替换成该类型的 子类型;
class ParentClass{//父类public int count() {//return 0;}Object method() {return "aa";}<T extends ParentClass> T getValue(T t) {//泛型方法System.out.println();return t;}
}class ChildClass extends ParentClass{//子类public int count() {//重写count()方法,由于返回类型是基本类型,不能变,必须是一致return 0;}public String method() {//重写method():访问权限增大,返回类型是Object的子类Stringreturn "aa";}ChildClass getValue(ParentClass ch) {//重写泛型方法getValue()return null;}
}
解析一下此例子中的泛型方法重写,父类中的泛型方法getValue()
进行类型擦除后,是:
ParentClass getValue(ParentClass t){return null;
}
所以,子类ChildClass
的方法重写是合理的。
作者:jinggod
出处:http://www.cnblogs.com/jinggod/p/8503153.html
类与接口(五)java多态、方法重写、隐藏相关推荐
- Java 编程问题:七、Java 反射类、接口、构造器、方法和字段
原文:Java Coding Problems 协议:CC BY-NC-SA 4.0 贡献者:飞龙 本文来自[ApacheCN Java 译文集],自豪地采用谷歌翻译. 本章包括涉及 Java 反射 ...
- Java学习笔记二十二:Java的方法重写
Java的方法重写 一:什么是方法的重写: 如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用方法时会优先调用子类的方法. 语法规则 返回值类型.方法名.参数类型及个数都要与父类继承的 ...
- Java中方法重写和方法重载的6个区别?
文章合集:gitee.com/mydb/interv- 方法重写(Override)和方法重载(Overload)都是面向对象编程中,多态特性的不同体现,但二者本身并无关联,它们的区别犹如马德华之于刘 ...
- jdbc是java语言编写的类和接口_JDBC——Java语言连接数据库的标准
JDBC概述 API JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Jav ...
- Java基础方法重写
文章目录 关于java语言当中的方法的覆盖 关于java语言当中的方法重载 示例代码: 关于java语言当中的方法的覆盖 1.方法覆盖又被称为方法重写,英语单词:override[官方]/overri ...
- 类与接口(四)方法重载解析
###一.方法重载简介 方法重载: 当两个(或多个)方法的名称相同,而参数的对应类型或个数不同时,我们就说方法重载了.当然,编译器也能识别出来. 编译器是如何识别调用了哪个方法? 在往下讲前,我们先来 ...
- 判断两个学生类对象是否一致使用equals方法重写时判断条件使用“==”、“String自带的equals”不同所带来的问题
重写equals方法判断条件使用"=="的情况 public class Test06{public static void main(String[] args){Student ...
- 手把手教我班小姐姐学java之方法重写与方法重载
方法重写 子类从父类中继承方法.有事,子类需要修改父类中定义的方法的实现,这就是方法重写. 重写的好处在于子类可以根据需要,定义特定于自己的行为. 在面向对象原则里,重写意味着可以重写任何现有方法.实 ...
- Java中方法重写和重载的区别
一.方法的重载 - 重载(overloading) 是在一个类里面,方法名字相同,而参数不同.返回类型可以相同也可以不同.每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表. 重载的规则 ...
- [Java] Overrid 方法重写
//父类 class OverridSuperClass { //父类无参数方法 public void Show() { System.out.println ...
最新文章
- 解决push的时候有时候会卡一下的问题
- Cache系列:spring-cache简单三步快速应用ehcache3.x-jcache缓存(spring4.x)
- 用Tableau画Voronoi Treemap
- keras从入门到放弃(二十)LSTM处理 电影评价预测
- AGC044E Pandom Pawn(期望+凸包)
- POJ 1064 分割线缆(二分查找)
- python mysql autocommit_MySQLdb autocommit的坑
- (完美解决)Tomcat启动提示At least one JAR was scanned for TLDs yet contained no TLDs
- rabbitmq如何清空queue队列数据
- esxi linux 网络不可达,将ESXI所有的端口组迁移到分布式交换机的步骤
- NEYC 2017 游记
- 最大流的四种常用算法
- B站五面面经(附过程、答案)
- 十分钟写一个好玩的app
- 解决idea项目没有蓝色小方块
- 华为鸿蒙未来生态,华为王成录:鸿蒙生态构建成功后,未来移动产业20年将属于中国...
- 年轻人看不起牙,但年轻人能靠这门生意赚钱吗?
- SpriteKit从零开始~Physics and Collisions
- 短信收到的发票链接打不开解决办法
- 【Swing入门教程】一步一步做Netbeans(1):类Netbeans的主界面