java 继承运行结果解释
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 继承运行结果解释相关的知识,希望对你有一定的参考价值。
package a;
public class A extends Base
private String name = "a";
public A()
System.out.println("A");
System.out.println(name);
tellName();
printName();
public void tellName()
System.out.println("A tell name: " + name);
public void printName()
System.out.println("A print name: " + name);
public static void main(String[] args)
new A();
class Base
private String name = "base";
public Base()
System.out.println("Base");
System.out.println(name);
tellName();
printName();
public void tellName()
System.out.println("Base tell name: " + name);
public void printName()
System.out.println("Base print name: " + name);
运行结果:
Base
base
A tell name: null
A print name: null
A
a
A tell name: a
A print name: a
不懂为什么,求大神解救
用的debug模式,设断点,就可以自己看了
new A(); ,A继承Base, Base的构造方法:
System.out.println("Base");//输出BaseSystem.out.println(name); //输出name
tellName(); //指向A的tellName()方法,此时name=null;
printName(); // 指向A的方法,此时name=null;
谢谢你的方法,又学到了
追答不谢
参考技术Anew A()的执行过程:
跳到A的构造方法;
因为A继承了Base,跳到B的构造方法;
B的构造方法执行时先执行private String name = "base";
执行B的构造方法,打印那两行信息;
调用方法时,A类重写了Base类的那俩方法,所以调用A类的方法,此时A类的name属性还未初始化所以输出null;
B的构造方法调用完毕,返回A的构造方法;
初始化属性private String name = "a";
执行那4行代码。
包含知识点:
无参的构造方法会调用父类的无参构造方法。
不指定执行方法的类的时候,优先去子类里找被重写的方法。
在调用完父类构造方法后,才会初始化属性。
java笔记
1、类只能单继承,class1 extends class2,但是接口之间可以多继承
2、java语言是解释型语言,被编译成字节码格式后,由java解释器进行解释执行
3、变量名不能是数字开头
4、assert关键字使用,断言
assert boolean表达式:“结果”,如果不满足把结果放在AssertionError异常中并抛出
5、成员变量在方法体外,类中,但是必须实例化对象才可以调用
而类变量是加了static的成员变量,可以直接用类名调用
6、
byte是8位,short16位,int32位,long64位
float32位单精度,double64位双精度
char16位unicode字符
7、boolean类型不能进行运算
大类型转小类型要强制转换
浮点数转整数是舍弃小数位
8、public所有包都可以访问
protected同一包内,子类
default同一包内
private本包
9、接口里的变量都隐式声明为public static final不可改变,类调用,可见
10、
&都是1就是1,否则是0
|只要有一个1就是1
^不同就是1,相同就是0
~按位翻转
<<按位左移
>>按位右移
>>>按位右移补零,右移出来的空位补零
&&逻辑与,2个逻辑都是true才是真
||逻辑与,只要有一个是真就是真,判断第一个之后就不判断第二个了
11、 a instanceof b
instance就是实例的意思
判断a是不是b一个实例,如果a和b互为继承关系也是true
12、运算符优先级
括号类>非,翻转>乘除余>加减>移位>按位操作>逻辑操作>赋值类>逗号
13、switch支持String
14、把基本数据类型转换为对应的引用类型是装箱Integer x=5;,相反是拆箱
15、parseInt()把字符串解析为int类型
Math.round()四舍五入
16、Character类
isLetter()是否是一个字母
isDigit()是否是一个数字
isWhitespace()是否是一个空格
17、字符串是不可改变的,只能是创建一个新的字符串
charAt(int index)返回索引出的char
String[] split(String regex)以正则表达式来拆分字符串
char[] toCharArray()把此字符串转换为一个新的字符数组
String trim()返回此字符串去掉头尾空白的副本
18、String不可修改,但是StringBuffer和StringBuilder可以
其中StringBuilder运行速度快,但是不是线程安全的
StringBuilder ss=new StringBuilder();
ss.append();追加
ss.delete();移除
19、Date()获取当前时间
20、方法重载就是参数不同,方法名字相同的多个方法
21、构造方法名字跟类名一样,但是没有返回
22、Scanner scan=new Scanner(System.in);
scan.hasNext();有就是true
String s=scan.next();
23、检查性异常:程序言无法预见的,
运行时异常:是可以被程序员避免的异常
24、继承
如果子类重写了父类的方法,即所有元素相同只有函数内容不同的方法,那么父类的原方法对子类来说就是隐藏的,再调用的话调用的是改写后的方法
如果想调用父类的方法,可以用super
属性也可以直接继承直接用,属性也可以改写
25、接口
接口是一种规范,接口中的方法都是public abstract抽象,都没有方法体
有了接口,就知道实现了这个借口的类里面都有些什么,如果没有借口,就需要每一个类都去看看,反射性能差?
26、为什么子类构造函数中的第一行要加上super();
子类在对对象进行实例化的时候,会先创建父类对象,所以需要先调用父类的构造函数,所以子类中的所有构造函数的第一行都会隐式的添加super()
27、重写是子类父类之间的方法改造,重载是同一个类方法之间的多态
28、
枚举是一个特殊的类
里面存储了一些常量。例如SPRING,这些常量也可以带参数例如SPRING(1,"spring")
如果这些常量带了参数,那么就需要给他们配备相对应的构造函数,参数长度要一样
enum(int a,String b){this.a=a;this.b=b;}不然就会报错
使用这些常量的时候通常是
枚举类名.value()可uo返回枚举的值的数组
29、hashmap和hashtable区别,这2个都是map的实现类,即都是键值类型的
(1)hashtable是线程安全的,即可多个线程同时进行而不会对结果产生影响,hashmap不是
(2)hashtable不接受null键null值,而hashmap接受
(3)hashtable性能在单线程情况下不如hashmap
30、List接口
(1)ArrayList,元素间无间隔当数组大小不够时,要将数组复制到新的存储空间里,适合随机查找和遍历,不适合插入删除
(2)Vector。支持线程同步,就是按顺序进行,同步花费大,所以速度慢
(3)LinkedList,以上2个内部是通过数组实现的,LinkedList是链式存储,适合动态插入和删除,但是遍历慢
31、Stack是Vector的子类,是一个后进先出的栈,除了父类的一些add等操作数组的方法,Stack增加了自己的方法 push:项压入栈,pop:移除项,peek:查看栈顶对象
32、collection是List和Set的父接口
(1)List的实现类有Stack,Vector,这2个是传统的,新的是Arraylist,LinkedList,List允许有重复的元素
(2)Set的实现类有HashSet,TreeSet,一个不包含重复元素的 collection接口
33、collection接口继承于Iterable。Iterator只有一个方法就是iterator()。返回一个迭代器
34、任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。
35、使用集合框架的时候,如果没有使用泛型,那么从集合中取出的对象就是Object的,需要进行强制转换,如果使用了泛型,那么所有的强制转换都是自动和隐式的
36、泛型可以使用在集合框架中,也可以使用在以下情况:
如果你想写一个工具类,实现2个元素的相加,但是你不确定这2个元素的类型,你就可以写一个泛型类,这样的话,泛型类的元素类型就是待定,只有在对象被创建的时候才确定,这也有一个好处,就是创建出来的对象只接受一种类型的元素
public 类名<T>{}
37、序列化
是指将java对象转化为字节序列的过程,反序列化相反
writeObject()序列化
readObject()反序列化
序列化的用处,在将数据进行持久化,或者网络传输时,需要将数据转化为可在网络上传送的二进制序列,这时候序列化的好处就体现出来了
38、网络编程
(1)背诵的:
OSI分层模型:应用层 TCP/IP分层模型:应用层
表示层
会话层
传输层 传输层
网络层 网络层
数据链路层 数据链路层
物理层 物理层
网络层--------IP(网络之间的互联协议)
传输层--------TCP(传输控制协议)、UDP(用户数据报协议)
应用层--------Telnet(Internet远程登录服务的标准协议)、FTP(文本传输协议)、HTTP(超文本传输协议)
TCP:面向连接一种保证可靠传输的协议,用于传输顺序,无差别的数据流
UDP:无连接,每个数据报都是独立的信息,是一种非可靠的协议
可靠的传输时有代价的,传输效率降低了,因为内容的检验会占用计算机处理时间和网络带宽
OSI分层模型:
应用层:是对外提供具有文件传输,文件管理等功能的接口,代表协议:HTTP、FTP、Telnet,就像a公司要向b公司发送一份表单
表示层:是翻译官,把数据按照网络能理解的方案进行格式化,就像a,b公司商量使用英文文档,表示层对文档进行翻译加密
会话层:建立起网络中两点之间的通信链接,就像外交部建立并记录本次会话,从a公司发送开始,到b公司接收到为止,会话结束
传输层:对数据包进行分割成数据段,并进行传输排序,单位是数据段,代表协议:TCP、UDP。就像快递员,负责把表单送到快递公司,该层向高层屏蔽了下层数据通信的细节,所以快递公司怎么送快递上层并不知道
网络层:将网络地址翻译成对应的物理地址,代表协议:IP,单位是数据包。就像各个快递中心,负责分发快递
数据链路层:控制网络层与物理层之间的通信,保证可靠传输,单位是帧。就像快递公司具有负责把包裹完整准时送达目的地的义务一样
物理层:最底层,提供最基础的物理连接,单位是比特。就像交通工具,运送快递
----------------------------------------------------------------
39、基于url的网络编程 待定???
(1)创建一个url: public URL("http","www.baidu.com", 80, "demo.html");
(2)解析一个URL:
public String getProtocol() 获取该URL的协议名。
public String getHost() 获取该URL的主机名。
public int getPort() 获取该URL的端口号,如果没有设置端口,返回-1。
public String getFile() 获取该URL的文件名。
------------------------------------------------------------------
40、读取
*inputStream是所有字节输入流中的超类,其余的输入流是都是继承他的,或者继承他的子孙类
子类有:
FileInputStream用于创建一个面对文件的输入流,虽然叫做输入流,但是他是用来读取字节的,可以用于读取任何文件,因为所有的文件都可以转化为字节
FileInputStream(String filePath)创建
read()读取一个字节
read(byte b[])读取多个字节,存储于b中
ByteArrayInputStream是一个面对字节数组的输入流,用于读取数组
ByteArrayInputStream(byte[] buf)创建
*Reader是读取字符流的抽象类,InputStream提供的是字节流的读取,而非文本读取,这是和Reader类的根本区别。
Reader读取出来的是char数组或者string数组,而inputStream读取出来的是byte数组
BufferedReader从字符输入流读取文本,用于包装那些read操作开销很大的Reader,例如FileReader,InputStreamReader,用于提高读取效率,因为BufferReader的构造参数是InputStream,但是InputStream是抽象类,不能被实例化,所以只能实例化他的子类例如FileInputStream再把对象赋给InputStream。所以具体实现是
InputStream in=new FileInputStream("C:\\Users\\Administrator\\Desktop\\a.txt");//创建一个指向文件的字节读取流
InputStreamReader isr=new InputStreamReader(in);//把字节读取流转换成字符读取流
BufferedReader br=new BufferedReader(isr);//把低效率的无缓冲的包装成有缓冲的字符读取流
System.out.println(br.readLine());//输出一整行String
---虽然这样可以读取中文,但是会丢失,不知道为啥?
Reader如何实现循环读取?
readLine()函数会以回车作为一行的终点,并且在最后一行的时候返回null
output是写入,跟input的操作基本一样read变成write,流用完要关闭close(),关闭前要flush()
writer的子类有:
bufferedWriter,作用跟bufferedReader一样
OutputStream fos=new FileOutputStream("C:\\Users\\Administrator\\Desktop\\a.txt",true);//创建一个指向文件的字节写入流,true是是否追加的意思
OutputStreamWriter osw=new OutputStreamWriter(fos,"utf-8");//转换成字符写入
BufferedWriter bw=new BufferedWriter(osw);//提高效率
bw.write("啦啦");//写入
bw.newLine();//换行
bw.flush();//刷新才会写入成功
PrintWriter是一个类似于BufferedWriter的类,除了没有缓冲区外,功能比BufferedWriter多:
其一:PrintWriter可以创建自动刷新
OutputStream fos=new FileOutputStream("C:\\Users\\Administrator\\Desktop\\a.txt",true);//创建执行文件的字节写入流,true是追加
PrintWriter pw=new PrintWriter(fos,true);//PrintWriter可以直接接受OutputStream流,BufferedWriter只能接受Writer流,true是是否自动刷新的意思
pw.println("asd");//这个是自动刷新加自动换行的意思,
其二:PrintWriter可以写入任意类型的数据,对象都可以写,BufferedWriter只能写char,String
41、抽象类和接口的区别
抽象类中的抽象方法可以有方法体,而且抽象方法必须被重写,也可以有非抽象的方法
接口中的方法都是abstract的,这些方法都必须被实现,所以接口也是特殊的抽象类
接口里的变量都是public、static的,而抽象类中的变量知识普通变量
如果一个类实现了一个接口,但是没有实现所有的方法,那么这个类只能是抽象类
42、
bit:位,一个二进制数据0或者1
byte:字节,存储空间的基本计量单位,1byte=8bit
一个英文字符就是一个字节,英文标点符号也是一个字节
一个汉字就是2个字节,一个汉字标点符号也是2个字节
43、多线程学习
(1)进程和线程
理解:进程和线程都是对CPU工作时间段的描述,只不过颗粒度不同,程序的执行就是加载程序的上下文环境,执行程序,保存程序的上下文环境,这个程序里会有代码段abc,这些代码段就是线程,CPU的执行就是这个程序执行一下,然后换别的程序执行一下
背诵:
进程是一个动态的实体,是程序的一次执行过程,是操作系统的分配资源的基本单位。一个进程包含多个线程,每个线程都是独立调度和独立运行的基本单位。每一个进程都拥有不同的虚拟地址空间,但是同一进程里的线程共享同一地址空间
(2)并行和并发
并行是多个cpu同时处理一段逻辑,是真正意义上的同时
并发是通过cpu调度算法,让用户看上去同时执行,其实是频繁切换
(3)线程安全:就是在并发的情况下,该代码经过多线程使用,对结果没有产生影响
(4)同步:通过人为的控制和调度,让多线程访问成为线程安全,这就是同步
(5)线程的状态
new:新建状态
Runnable:可运行状态
Running:运行状态
Dead:死亡状态
Blocked:阻塞状态
Thread类的api
int activeCount()当前线程组的活动线程的数目
long getId()返回该线程的标示符
String getName()返回线程的名称
int getPriority()返回优先级
void interrupt()中断线程
void join()在A中执行B.join(),那么A会等待B执行完再执行
void run()实际操作代码
void setPriority()更改线程的优先级
void sleep()休眠
void strat()执行,jvm会调用该线程的run方法
void yield()暂停执行,执行其他线程
void wait()进入等待池,释放所持有的锁
sleep()是休眠,在这段时间内该线程是肯定不会被执行的,而yield()是让出cpu,让同优先级的线程又在同一起跑线上,原线程还是有继续执行的机会
Object.notify();唤醒在此监视器上等待的单个线程
Object.wait();让当前线程进入等待,只能由此对象唤醒
interrupt()只能用于打断处于wait/sleep/join状态的线程,被打断的线程会抛出InterruptedException
synchronized同步,同一对象的多个同步方法不能同时被访问,不同对象的多个同步方法可以同时被访问
以上是关于java 继承运行结果解释的主要内容,如果未能解决你的问题,请参考以下文章