第一章 对象导论
第二章 一切都是对象
前两章是从宏观来介绍面向对象编程相关的内容,挺有意思,可多看几遍。
笔记从第三章开始:
第三章 操作符
别名现象
赋值对象引用会发生什么
将一个对象赋值给另一个对象,实际上是将引用从一个地方复制到另一个地方。
若想保持两个对象彼此独立,不建议直接操作对象内的域。容易导致混乱,且违背了面向对象程序设计的原则。
解决方案:深克隆
https://blog.youkuaiyun.com/DeMonliuhui/article/details/54572908
https://blog.youkuaiyun.com/nishuishenhan/article/details/4693710
https://blog.youkuaiyun.com/qq_28081081/article/details/80455150
==和equals
1)对于==比较的是值是否相等
如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量,equals继承Object类,比较的是是否是同一个对象
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
int x = 10;
int y = 10;
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(x == y); // 输出true
System.out.println(str1 == str2); // 输出false
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2));//输出true
System.out.println(str1 == str2);//输出false
上述str1和str2都是在堆内存中创建了对象!new了
String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2));//输出true
System.out.println(s1 == s2);//输出true
为什么第二个会是true呢?
涉及到了内存中的常量池,常量池属于方法区的一部分,当运行到s1创建对象时,如果常量池中没有,就在常量池中创建一个对象"abc",第二次创建的时候,就直接使用,所以两次创建的对象其实是同一个对象,它们的地址值相等。
第五章 初始化与清理
数据初始化顺序
类加载时:(静态只执行一次)父类——静态变量
父类——静态初始化块
子类——静态变量
子类——静态初始化块
类创建时:(每次创建类执行)
父类——变量
父类——初始化块
父类——构造器
子类——变量
子类——初始化块
子类——构造器
第六章 访问权限控制
JAVA解释器运行过程(加载包过程)
首先,找出环境变量CLASSPATH,CLASSPATH包含一个或多个目录,用作查找.class文件的根目录。从根目录开始,解释器获取包的名称并将每个句点替换成反斜杠,以从CLASSPATH根中产生一个路径名称(于是,package foo.bar.baz会变成foo\bar\baz或foo/bar/baz或者其他;这一切取决于操作系统)。得到的路径会与CLASSPATH中的各个不同的项相连接,解释器就在这些目录中查找与你所要创建的类名称相关的.class文件。(解释器还会去查找某些涉及java解释器所在位置的标准目录。)
private构造器
构造器私有化,谁也无法创建该类的对象,别人该怎样使用这个类呢?1、创建一个static方法,创建一个新的对象并返回一个对它的引用。如果想在返回引用前做一些额外的工作,或者记录到底创建了多少个对象,此种做法可行。
class Sundae {
private Sundae() {}
public static Sundae makeASundae() {
return new Sundae();
}
}
2、单例模式singleton
class Soup2{
private Soup2(){}
private static Soup2 ps1=new Soup2();
public static Soup2 access(){
return ps1;
}
}
Soup2类的对象是作为Soup2的一个static private 成员而创建的,所以有且仅有一个,而且除非是通过public方法access(),否则是无法访问到它的。
第七章 复用类
在组合和继承之间选择
组合:想在新类中使用现有类的功能而非是它的接口(has-a)有一个继承:使用某个现有类,并开发它的特殊版本 (is-a)是一个
到底该用组合还使用继承?
问一问自己是否需要从新类向基类进行向上转型。
如果必须向上转型,则继承是必须的;但如果不需要,则应当好好考虑自己是否需要继承。
其它:private保留“更改底层实现”的权利。然后通过protected方法来控制类的继承者的访问权限
第八章 多态
多态:编译器一直不知道对象的类型,但是方法调用机制能找到正确的方法体,并加以调用。1、只有非private方法才可以被覆盖
2、只有普通方法的调用可以使多态的
3、如果某个方法是静态的,它的行为就不具有多态性。(静态方法是与类,而并非单个的对象相关联的)
4、父类一个变量,子类一个同名变量不会覆盖父类的
Super sup=new Sub();
sup.field变量还是父类的,sup的普通方法是子类的
因为任何域访问操作都将由编译器解析,因此不是多态的。