Java基础2:基本数据类型与常量池
本文会结合虚拟机对引用和对象的不同处理来介绍三大特性的原理。
三大特性:继承 封装 多态
继承
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 {
@Override
public void cook() {
System.out.println("mom cook");
}
}
}
封装
封装主要是因为Java有访问权限的控制。public > protected > package = default > private。封装可以保护类中的信息,只提供想要被外界访问的信息。
类的访问范围
A、public 包内、包外,所有类中可见
B、protected 包内所有类可见,包外有继承关系的子类可见
(子类对象可调用)
C、(default)表示默认,不仅本类访问,而且是同包可。
D、private 仅在同一类中可见
多态
多态一般可以分为两种,一个是重写overwrite,一个是重载override。
重写是由于继承关系中的子类有一个和父类同名同参数的方法,会覆盖掉父类的方法。重载是因为一个同名方法可以传入多个参数组合。
注意,同名方法如果参数相同,即使返回值不同也是不能同时存在的,编译会出错。
从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");
// }
下一节具体介绍了基本数据类型以及常量池,具体请见:
https://blog.csdn.net/a724888/article/details/80041698
Java基础2:基本数据类型与常量池的更多相关文章
- JAVA学习(三):Java基础语法(变量、常量、数据类型、运算符与数据类型转换)
Java基础语法(变量.常量.数据类型.运算符与数据类型转换) 1.变量 Java中.用户能够通过指定数据类型和标识符来声明变量.其基本的语法为: DataType identifier; 或 Dat ...
- JAVA基础知识之数据类型
JAVA的数据类型知识点主要包括基本数据类型,包装类,字符串类(String,StringBuffer, StringBuilder区别和用法),数组,数据类型转换等等,暂时只想到这么多,后面会再补充 ...
- Java中堆、栈、常量池分析
栈用于存储局部变量,包括基本类型的变量(方法语句块内部定义的变量.方法中的形参).引用类型的变量,它们都是存储在各自的方法栈中,随着方法的执行完成而消失: 堆用于存储引用类型变量所指向的对象,包括普通 ...
- 基本数据类型的常量池与String类型常量池解析
抛出样例: Integer a1 = new Integer(123); Integer a2 = new Integer(123); System.out.print ...
- Java - String 的字面量、常量池、构造函数和intern()函数
一.内存中的 String 对象 Java 的堆和栈 对于基本数据类型变量和对象的引用,也就是局部变量表属于栈内存: 而通过 new 关键字和 constructor 创建的对象存放在堆内存: 直接的 ...
- JAVA自动装箱拆箱与常量池
java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的 ...
- Java基础语法(一)---关键字、常量、变量、运算符
一.关键字 定义:被Java赋予了特殊含义的单词. 特点:体现上都是英文小写. 1. 用于定义数据类型的关键字 基本数据类型: 整数类型:byte short int long 浮点类型:f ...
- Java基础之基本数据类型
前言:Java内功心法之基本数据类型,看完这篇你向Java大神的路上又迈出了一步(有什么问题或者需要资料可以联系我的扣扣:734999078) 变量就是申请内存来存储值.也就是说,当创建变量的时候,需 ...
- java基础(三) -基本数据类型
变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. 因此,通过定义不同类型的变量,可以在内存 ...
随机推荐
- 网络攻击技术:SQL Injection(sql注入)
网络攻击技术开篇——SQL Injection 1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库被黑客公开发布,600万用户的登录名及密码被公开泄露,随后又有多家网站的用户密码 ...
- C++第三课:类的使用(一)[个人见解]
说到C++语言的类,也称对象.在C++中首先得了解的三大特性:继承.封装.多态. 使用C++类,间接的反映出你所学习C++的深度,这章很重要,但小编未必能全部讲到,还望谅解. 类是C++语言中新添加的 ...
- esb和eai的区别
话说SOA也推了很多年了,出现了比如ESB.SCA.jbi等各类技术和标准,乱的很.各类比较也说的云里雾里,在下理一理,按自己的观点说说. 先说说esb和eai的区别. 个人观点:esb就是eai+设 ...
- meta标签的用处详解
meta标签的用处: 用来描述html文档的一个属性.列如作者.日期和时间,网页描述,关键字,页面刷新等. 是文档最基本的元数据 元数据(metadata): 用来概括描述数据的一些基本数据 meta ...
- 怎样做ie兼容性
1.<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />强制把不标准的转 ...
- [微信小程序]编译.wxss出错,2 not found
小程序新建项目就出错:2 not found 编译.wxss文件出错(不是一般的郁闷,新建项目就报错...) 大概的情况是开发工具没有更新.或更新不到, 第一,可以删掉开发工具重新下载最新安装: 第 ...
- React state和props使用场景
一个组件的显示状态可以由内部状态state.外部参数props所决定. props: 1.props 是从外部传进组件的参数,主要是父组件向子组件传递数据. 2.props 对于使用它的组件来说是只读 ...
- linux操作命令之帮助命令
一.man命令的帮助: man 命令名 获取指定命令的帮助 例如man ls 查看ls的帮助 man man可以看到man有8个级别的man帮助命令使用场景 1.查看命令的帮助 2.查看可被内核调用的 ...
- OpenCV读写摄像头并写入视频
#include <opencv2/opencv.hpp>using namespace cv;#include <iostream>using namespace std; ...
- 查询Python版本