【Java基本功】一文了解Java中继承、封装、多态的细节
本节主要介绍Java面向对象三大特性:继承 封装 多态,以及其中的原理。
本文会结合虚拟机对引用和对象的不同处理来介绍三大特性的原理。
继承
Java中的继承只能单继承,但是可以通过内部类继承其他类来实现多继承。
public class Son extends Father{public void go () {System.out.println("son go");}public void eat () {System.out.println("son eat");}public void sleep() {System.out.println("zzzzzz");}public void cook() {//匿名内部类实现的多继承new Mother().cook();//内部类继承第二个父类来实现多继承Mom mom = new Mom();mom.cook();}private class Mom extends Mother {@Overridepublic void cook() {System.out.println("mom cook");}}}
封装
封装主要是因为Java有访问权限的控制。public > protected > package = default > private。封装可以保护类中的信息,只提供想要被外界访问的信息。
类的访问范围
A、public 包内、包外,所有类中可见B、protected 包内所有类可见,包外有继承关系的子类可见(子类对象可调用)C、(default)表示默认,不仅本类访问,而且是同包可。D、private 仅在同一类中可见
多态
多态一般可以分为两种,一个是重写,一个是重载。
重写是由于继承关系中的子类有一个和父类同名同参数的方法,会覆盖掉父类的方法。重载是因为一个同名方法可以传入多个参数组合。注意,同名方法如果参数相同,即使返回值不同也是不能同时存在的,编译会出错。从jvm实现的角度来看,重写又叫运行时多态,编译时看不出子类调用的是哪个方法,但是运行时操作数栈会先根据子类的引用去子类的类信息中查找方法,找不到的话再到父类的类信息中查找方法。而重载则是编译时多态,因为编译期就可以确定传入的参数组合,决定调用的具体方法是哪一个了。
向上转型和向下转型:
public static void main(String[] args) {Son son = new Son();//首先先明确一点,转型指的是左侧引用的改变。//father引用类型是Father,指向Son实例,就是向上转型,既可以使用子类的方法,也可以使用父类的方法。//向上转型,此时运行father的方法Father father = son;father.smoke();//不能使用子类独有的方法。// father.play();编译会报错father.drive();//Son类型的引用指向Father的实例,所以是向下转型,不能使用子类非重写的方法,可以使用父类的方法。//向下转型,此时运行了son的方法Son son1 = (Son) father;//转型后就是一个正常的Son实例son1.play();son1.drive();son1.smoke();//因为向下转型之前必须先经历向上转型。//在向下转型过程中,分为两种情况://情况一:如果父类引用的对象如果引用的是指向的子类对象,//那么在向下转型的过程中是安全的。也就是编译是不会出错误的。//因为运行期Son实例确实有这些方法Father f1 = new Son();Son s1 = (Son) f1;s1.smoke();s1.drive();s1.play();//情况二:如果父类引用的对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,//但是运行时会出现java.lang.ClassCastException错误。它可以使用instanceof来避免出错此类错误。//因为运行期Father实例并没有这些方法。Father f2 = new Father();Son s2 = (Son) f2;s2.drive();s2.smoke();s2.play();//向下转型和向上转型的应用,有些人觉得这个操作没意义,何必先向上转型再向下转型呢,不是多此一举么。其实可以用于方法参数中的类型聚合,然后具体操作再进行分解。//比如add方法用List引用类型作为参数传入,传入具体类时经历了向下转型add(new LinkedList());add(new ArrayList());//总结//向上转型和向下转型都是针对引用的转型,是编译期进行的转型,根据引用类型来判断使用哪个方法//并且在传入方法时会自动进行转型(有需要的话)。运行期将引用指向实例,如果是不安全的转型则会报错。//若安全则继续执行方法。}public static void add(List list) {System.out.println(list);//在操作具体集合时又经历了向上转型// ArrayList arr = (ArrayList) list;// LinkedList link = (LinkedList) list;}
总结: 向上转型和向下转型都是针对引用的转型,是编译期进行的转型,根据引用类型来判断使用哪个方法。并且在传入方法时会自动进行转型(有需要的话)。运行期将引用指向实例,如果是不安全的转型则会报错,若安全则继续执行方法。
编译期的静态分派
其实就是根据引用类型来调用对应方法。
public static void main(String[] args) {Father father = new Son();静态分派 a= new 静态分派();//编译期确定引用类型为Father。//所以调用的是第一个方法。a.play(father);//向下转型后,引用类型为Son,此时调用第二个方法。//所以,编译期只确定了引用,运行期再进行实例化。a.play((Son)father);//当没有Son引用类型的方法时,会自动向上转型调用第一个方法。a.smoke(father);//}public void smoke(Father father) {System.out.println("father smoke");}public void play (Father father) {System.out.println("father");//father.drive();}public void play (Son son) {System.out.println("son");//son.drive();}
方法重载优先级匹配
public static void main(String[] args) {方法重载优先级匹配 a = new 方法重载优先级匹配();//普通的重载一般就是同名方法不同参数。//这里我们来讨论当同名方法只有一个参数时的情况。//此时会调用char参数的方法。//当没有char参数的方法。会调用int类型的方法,如果没有int就调用long//即存在一个调用顺序char -> int -> long ->double -> ..。//当没有基本类型对应的方法时,先自动装箱,调用包装类方法。//如果没有包装类方法,则调用包装类实现的接口的方法。//最后再调用持有多个参数的char...方法。a.eat('a');a.eat('a','c','b');}public void eat(short i) {System.out.println("short");}public void eat(int i) {System.out.println("int");}public void eat(double i) {System.out.println("double");}public void eat(long i) {System.out.println("long");}public void eat(Character c) {System.out.println("Character");}public void eat(Comparable c) {System.out.println("Comparable");}public void eat(char ... c) {System.out.println(Arrays.toString(c));System.out.println("...");}// public void eat(char i) {// System.out.println("char");// }
【Java基本功】一文了解Java中继承、封装、多态的细节的更多相关文章
- OOP面向对象 三大特征 继承封装多态
OOP面向对象 ----三大特征 继承封装多态 面向对象(Object Oriented,OO)是软件开发方法.面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统.交互式界面.应用结构 ...
- [转]Java中继承、多态、重载和重写介绍
什么是多态?它的实现机制是什么呢?重载和重写的区别在那里?这就是这一次我们要回顾的四个十分重要的概念:继承.多态.重载和重写. 继承(inheritance) 简单的说,继承就是在一个现有类型的基础上 ...
- Java面向对象理解_代码块_继承_多态_抽象_接口
面线对象: /* 成员变量和局部变量的区别? A:在类中的位置不同 成员变量:在类中方法外 局部变量:在方法定义中或者方法声明上 B:在内存中的位置不同 成员变量:在堆内存 局部变量:在栈内存 C:生 ...
- Java类与类的关系、继承与多态、重写与重载
Java类与类的关系 (1)is-a包括了 继承,实现关系 (2)has-a包括了 关联,聚合,组合关系 (3)use-a包括了 依赖关系 实现关系: 实现指的是一个class类实现interface ...
- Java面向对象笔记 • 【第3章 继承与多态】
全部章节 >>>> 本章目录 3.1 包 3.1.1 自定义包 3.1.2 包的导入 3.1.3 包的访问权限 3.1.4 实践练习 3.2 继承 3.2.1 继承概述 3 ...
- python中继承和多态
继承和多态 继承 引入继承 我们有这样一个需求 模仿英雄联盟定义两个英雄类 1.英雄要有昵称.攻击力.生命值属性 2.实例化出两个英雄对象 3.英雄之间可以互殴,被殴打的一方掉血,血量小于0则判断为死 ...
- C#中继承和多态
1.继承的概念 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用已存在的类的功能. 为了提高软件模块的可复用性和可扩充性,以便提高软件的开发效率,我们总 ...
- c语言中继承和多态的简单实现
C语言本身是不支持继承和多态的,但其实在 C 的世界里,有一套非常有名的面向对象的框架,用的也非常广,那就是 GObject,它是整个图形界面开发库 GTK 的基石,在IBM developerWor ...
- Java中继承与多态
Java类的继承继承的语法结构: [修饰符列表] class 子类名 extends 父类名{ 类体; }子类就是当前这个类,父类就是我们要复用的那个类java中只支持单继承 ...
- java中继承和多态的理解
继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父 ...
随机推荐
- [leetcode]91. Decode Ways解码方法
A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...
- 微软Office Online服务安装部署(一)
1.要使用office online功能,首先需要的是2台主机,并且主机的系统要求是windwos Server 我把他命名为Server和Client(两台服务器 用户必须为administrato ...
- abp xunit Can not register IHostingEnvironment. It should be a non-abstract class. If not, it should be registered before.”
在测试项目的ServiceCollectionRegistrar类提前注册.
- bootstrap 辅助工具
模板 https://startbootstrap.com/ 可视化bootstrap在线编辑器 https://www.layoutit.com/
- etcd-v2第三集
简单说下golang的etcd接口例子.etcd api有v2(http+json)和v3(grpc)两个版本,目前大家都用v2,所以... v2: https://github.com/coreos ...
- NC nc开发工具java虚拟机参数
-Dnc.exclude.modules=${FIELD_EX_MODULES} -Dnc.runMode=develop -Dnc.server.location=${FIELD_NC_HO ...
- Python12/11--盒子的显隐/布局/z-index/流式布局思想
1.盒子的显隐 display:none 在页面中不占位,采用定位布局后,显示隐藏都不会影响其他标签,不需要用动画处理时,一般用这个 opacoity : 0 在页面中占位,采 ...
- 《mysql必知必会》学习_第17章_20180807_欢
第17章:组合查询 P114 select vend_id ,prod_id,prod_price from products where prod_price <=5 ; select ven ...
- Servlet 中,out.print()与out.write()的区别
最近刚学习了Ajax,其中有通过$.getJSON的实现方式 由于前后端传递值的时候会通过流的方式进行传递,这就不得不涉及到这方面的知识了 PrintWrite out=response.getWri ...
- SQL Server PageIOLatch和PageLatch
Latch是轻量级的锁,它是SQL Server内部用来同步资源访问的一个数据结构,使数据的访问同步有序,这意味着,当一个线程获得资源R的Latch的独占使用权时,如果其他的线程也想访问这个Latch ...