【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面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父 ...
随机推荐
- js、jquery、jsp的区别
1.JSP全称是java server page JS全称是javaScript 2.最主要的区别是运行位置不同. JSP运行在后台服务器上,混合在HTML中的java程序段用于控制HTML的动 ...
- hdpi对应分辨率
ldpi QVGA (240×320) mdpi HVGA (320×480) hdpi WVGA (480×800),FWVGA (480×854) xhdpi 720P(1280*720) ...
- 解决 ora-28001 密码过期的处理办法
转载自:https://blog.csdn.net/pengyouchuan/article/details/12905623 操作步骤: $sqlplus / as sysdba ALTER PRO ...
- mysql 数据库设计
数据库设计 需求分析 *1.用户模块 用于记录记录注册用户信息 包括属性:用户名,密码,电话,邮箱,身份证号,地址,姓名,昵称... 可选唯一标志属性:用户名,电话,身份证号 存储特点:随系统上线时间 ...
- angular2 学习
一,angular2脚手架搭建 1,安装node 2,安装淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org 3,搭 ...
- Netsharp总体介绍
作者:秋时 日期:2014年02月05日 转载须说明出处 Netsharp交流群:338963050(请有详细的请求说明) Netsharp系列文章目录结构 Netsharp是一款免费的基于 ...
- java利用反射获取对象前后修改的内容(用于日志记录)
import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...
- Python语言中的按位运算
(转)位操作是程序设计中对位模式或二进制数的一元和二元操作. 在许多古老的微处理器上, 位运算比加减运算略快, 通常位运算比乘除法运算要快很多. 在现代架构中, 情况并非如此:位运算的运算速度通常与加 ...
- 获取sql 时间时分秒
select DATE_FORMAT(now(),'%Y-%m-%d %T') from dual; 年月日时分秒 select DATE_FORMAT(now(),'%T') from dual; ...
- Nginx+Tomcat反向代理利用certbot实现https
一.利用Let's Encrypt 免费生成HTTPS证书 1.下载安装certbot(Let's Encrypt ) 2.利用certbot生成证书 3.配置nginx的https证书 安装cerb ...