java学习笔记8

来源:互联网 发布:网络推广年度工作总结 编辑:程序博客网 时间:2024/05/16 13:54

1、可以把经常用到的一些函数封装成类,这样调用时只需new个对象出来即可使用。在有main函数的类中如果用到了其他的类,那么java会自动在(指定路径下)或当前目录下找其他类的class文件,若找不到,就把那个类的.java文件编译生成class文件。


2、当工具类中的没有特殊的数据需要访问时,就可以把函数都定义为静态的,别的类在使用的时候直接类名.函数就可以调用,不需要生成对象。但是别的类在调用工具类的时候依然可以通过new对象来调用函数,这时就可以把工具类中的构造函数私有化,这时别的类就不能new工具类的对象了。


3、如何把数组转换为字符串的形式?可以通过字符串和数组元素不断相加来把数组转为字符串(任何类型数据和字符串一相加就成了字符串

4、public class 中的public一来可以提高类的权限,二来可以保证类名和文件名是一致的,否则编译会出错。

文档注释的格式是固定的,写错javadoc是无法识别你的注释就的。

java运行class时会在指令路径下找,找不到就无法运行,没有特别指定路径时,默认是当前目录下。如果工具类和别的类(有main函数)不在一个路径下,一定要先把两个class文件的路径都设置在classpath中才行。运行完之后,记得再把路径改成当前目录下就ok。




同时注意生成的注释文档只会提取class文件中的public函数的注释,private函数的不会生成在注释文档中。


5、单例设计模式

之前讲静态变量时介绍,一个对象里的静态变量一旦被改变,那么所有对象里的静态变量都跟随着改变了,这在配置一些东西时是很好用的。但是把全部成员变量都定义成静态的形式那它们的生命周期又太长了。要是每个人都new一个对象,通过对象改变变量,那又是各改各的,不能实现改一次所有对象的那个成员变量跟着改变,所以有了单例设计模式。简单的说,它只对外提供一个对象,不允许外面别的类来new对象,大家都通过单例类提供的对象来进行修改某些变量。

不允许别的类new对象,那就要求本类的构造函数私有化,同时本类自己new一个对象,由于别的类不能通过new对象来调用本类中get(唯一对象)函数,所以必须通过类名.函数的形式来调用,这也就要求get(唯一对象)的函数必须是static类型的,而静态函数不能访问非静态变量,所以本类new出来的唯一对象的引用变量也必须是静态的。


通过上图这种形式也能得到那个唯一对象,但是不通过函数的方法得到的,相当于没有限制,因为函数可以加if判断,可以实现不满足要求的不给返回。

所以最好写成下图的形式:


具体举个例子


蓝色部分三句话,就保证了对象的唯一性。

第一句:类本身创建一个对象,并用Test 类型的成员变量t来指向,保证对象的唯一性,大家都来调用这个对象。static 是因为 下面的第三句返回了t,由于静态函数不能访问非静态的成员变量,所以要写成static类型,private是因为防止别的类通过Test.s就调用了唯一的对象,私有化后想调用唯一的对象必须通过函数的形式Test.getInstance( )的形式才可以(保证安全)。

第二句:把构造函数私有化,防止别的类new出新的对象,保证类本身new出的对象是唯一的。

第三句:对外提供一种方法,使得在别的类中能访问到这个唯一的对象。static是因为,在别的类中不能new对象来访问这个函数,那么就必须通过类名.函数名的形式访问,所以函数必须是static类型的。

内存示意图如下所示:


6、饿汉式单例模式和懒汉式单例模式;饿汉式单例开发时用的多,懒汉式面试时用的多。(其实差不太多,作用都一样)


7、父类就是由子类不断向上抽取共性而来的,这是继承的逆性思维。

java不直接支持多继承是因为会产生调用的不确定性。




java不支持多继承,但是可以通过多实现方式来达到目的。


java虽然不能多继承,但是可以多重(多层)继承。不能有多个爹,但是可以去当爷,老爷。

什么时候改继承呢?只要类和类之间存在所属关系,A类里所有功能,B类都应该具备,那就存在继承关系。

对于同名的变量,子类已经有的成员变量,就不去父类里面找。局部变量里有的,就不去堆中找成员变量。具体如下图中所示,子类父类都有num成员变量,但是优先找子类中的。


8、关键字super

super代表一个父类的空间(的引用),而this代表一个本类对象的引用,这是this和super不同的地方。


9、 在内存加载时,父类要早于子类加载到方法区,因为父类的都没有,子类从哪里继承呢?


方法区只存放(加载方法代码),而堆中的对象里只存放具体的属性数据(成员变量)。注意父类num的初始默认值和子类的是同样道理,一开始都是默认为0;

另外当父类的成员变量为私有的,那子类不能直接访问,要通过super.getNum( )的方法来得到。子类可以继承了父类的私有成员变量,但是不能直接通过super.num来获得。



10、继承中,子类父类的成员函数的关系

就算子类和父类中有重名的成员函数,new出子类对象调用重名函数时,子类自己有的就会调用自己的,不去调用父类的。虽然子类中有父类的那个函数,但是不执行父类,执行自己的,就如同父类的成员函数被覆盖了一样。


覆盖是父类的也能用,子类的也能用,但是用子类的。所以父类函数private时,那就不是覆盖了。覆盖就是重写override。除了权限子类函数权限要大于等于父类的函数权限,成员函数的其余的形式都要一模一样才行。



11、用手机的例子来说明什么时候使用覆盖:

覆盖的好处可以在不修改源代码的基础上,方便通过子类继承后哦覆盖重写来添加新的功能,而且还可以利用以前的已有代码。

下图中手机的call()功能不需要改变,所以子类继承,但是来电显示show()想增添新的功能,所以只需覆盖重写子类自己的show()方法,父类的show()方法也依旧存在,所以还可以通过super.show()来调用,但平时子类对象调用show()就默认用覆盖重写后的自己独有show()方法。


12、父类的构造函数子类不能继承也不能覆盖,子类构造函数里有调用父类的构造函数的语句:super( )


其实除了super()是隐藏没写的外,还有一句在最后隐藏的return()没写。如果父类的构造函数都是有参数的,那么子类的构造函数就没法调用父类的构造函数,就会报错,除非在子类的构造函数里第一句的地方写:super(指定类型参数);才不会报错。


子类对象初始化,没有父类构造函数的帮助是不可能完成的!同时注意:super()语句一般都是要(默认隐藏)放在子类构造函数的第一行。因为父类的初始化动作要先完成。

下图中子类有参构造函数第一句是this(),虽然不像平时第一句是super(),但是this()里的第一句还是(隐藏的)super()  

在java中所有的类都是从object这个类继承过来的,可以说object类是类中的上帝,老祖宗,所有类都是从它直接或间接继承过来的。所以类名后面就算不写继承extends,这个类也是从object类继承过来的。所以任何类的构造函数里第一句基本上隐藏的都是super(),除非第一行写的this(),因为super()和this()只有也必有一个在第一行。


13、java虚拟机在启动的时候就已经加载了object的类,这些都是系统方面默认会做的。

下面详细介绍子类对象的实例化(生成)过程





整个代码运行流程如下:

1,先加载类代码到方法区,父类先加载,子类后加载。之后在堆中new出一个子类对象z以及它内部的成员变量,并生成引用地址,子类的成员变量num在堆中的对象里默认初始化为0,之后子类的构造函数开始运行将对象初始化,子类构造函数第一句为super(),所以又调用父类的构造函数,父类构造函数中调用了show()函数,由于子类父类中都有show()函数,而现在是子类对象初始化,所以子类先在自己方法区空间里找show()方法,显示:zi show ...0 。此时子类构造函数的第一句super()函数执行完成,紧接着成员变量num开始显示初始化即 num=8,再接着才开始执行构造函数的第二句,如果此时第二句num=10,那么就将num由8变为10,也即num=8这个显示过程是在第一句和第二句之间执行的。

0 0
原创粉丝点击