📄 05. core java note.txt
字号:
4、Java中的运算符重载
java中唯一重载的运算符是String类型的“+”号,任何类型+String类型结果都为Stirng类型。
5、注意点:重载不仅出现在同一个类中,也可以出现在父子类中。
重载的方法只是刚好有相同名字的不同方法
方法的覆盖 (Override) 重写
继承之后,想改变由父类继承下来的方法。
1. 同样的方法名、参数列表、返回类型(从Java 5 起,返回类型可以是子类型)
2. 访问权限不能更小
3. 异常不能更宽 (可以抛出更少或是更窄的检查异常,或者任何非检查异常)
重构 (extract Method)
消除代码的重复,提高代码的可维护性。整理凌乱的代码,把可重用的代码块包装起来。
常用重复的方法封装成工具类(工具类太多则做成工具箱),一般都是静态方法和常量,没有属性。
在eclipse里,选中要重构的代码,右键Refactor-Extract Mathod 或(Shift+Alt+M)
创建对象的步骤
1、分配空间
2、初始化属性
3、调用构造方法
注:构造方法不能手工调用,在对象的生命周期内构造方法只调用一次。
构造方法 (参考day05的 TestCat.java)
构造方法是在生成对象的过程中调用的方法,但构造方法并不能创建对象。
new 对象的时候需要调用构造方法。
1、特点:没有返回值(连void也没有),方法名与类名相同。(如果加上 void 会变成普通方法。)
2、在不写构造方法时,系统会自动生成一个无参的构造方法。
3、请养成在每个类中自己加上无参构造方法的习惯。
格式为:public ClassName(){}
构造方法也可以是其他的限制符――private protected default
private 一般用在 singleton 模式中。
在一个对象的生成周期中构造方法只用一次,一旦这个对象生成,那么这个构造方法失效。
* 接口不能创建实例,因为没有构造方法
可以构造多个构造方法,但多个构造方法的参数表一定不同,或参数顺序不同
即属于不同的构造方法:-----------------------> 构造方法的重载
使用构造方法来初始化对象的状态:把初始化代码放到构造方法中,并且把构造方法设定成需要参数的
编译器一定会帮你写出没有参数的构造方法吗?不会
如果你已经写了一个有参数的构造方法,并且你需要一个没有参数的构造方法,则你必须自己动手写
如果类有一个以上的构造方法,则参数列表一定要不一样,我们可以认为这几个构造方法形成重载关系
如果我们提供了有参的构造方法,那么系统不会再提供无参的构造方法了。
这样当被子类继承时,如果子类构造方法不人为调用父类的有参构造方法就会出现异常。
构造方法可以通过 this 调用另外一个构造方法(this 此时必须在第一行语句)
匿名对象:
创建对象时,直接调用对象的方法而不定义对象的句柄。
如: person p1 = new person; p1.shout();
改写成: new person.shout(); //此方法执行完,此匿名对象也就变成了垃圾。
使用匿名对象的情况:
1. 此对象只需要一次方法调用。
2. 此对象作为实参传给一个函数调用。
this 当前对象 (参考day05 的TestThis.java)
谁调用该方法,在这一时刻谁就是该方法的当前对象;是个隐式参数,代表被构造的对象。
用this来区分实例变量和局部变量。
this.实例变量名 = 局部变量名 (将局部变量赋值给实例变量)
this()表示调用本类的其他构造方法,且只能放在一个方法中的第一行第一句。
构造方法可以通过this调用另外一个构造方法(this此时必须在第一行语句)
*super 关键字也是个隐形参数,代表被构造对象的父类。
同样也必须在构造方法的第一行
对象和对象引用的区别
对象好比一台电视机,对象引用好比电视机遥控。对象引用 中存的是对象的地址。
多个对象引用中存放的是同一个地址,表示该对象被多个对象引用所引用。
面向对象的三大特性:
封装(Encapsulation)、继承(Inheritance)、多态polymiorphism
封装:
1.定义:指一个对象的内部状态对外界是透明的,对象与对象之间只关心对方有什么方法,而不关心属性。
封装使实现的改变对架构的影响最小化。封装后的代码更具有安全性、可扩展性和可维护性。
2.原则:封装使对象的属性尽可能的私有,根据需要配上相应的get/set方法,对象的方法尽可能的公开。
该隐藏的一定要隐藏,该公开的一定要公开。
3.方法公开的是声明而不是实现。使方法实现的改变对架构的影响最小化。
4.访问权限控制从严到宽
private :仅本类成员可见
default :本类+同包类可见(默认)
protected:本类+同包+不同包的子类
public :公开
注:这里的同包指的是跟父类所在的包相同。
5、完全封装:属性全部私有,并提供相应的get/set方法。
优点:
1.事物的内部实现细节隐藏起来
2.对外提供一致的公共的接口――间接访问隐藏数据
3.可维护性
一、继承:
1 定义:基于一个已存在的类构造一个新类。
继承已存在的类就是复用这些类的方法和属性,在此基础上,还可以在新类中添加一些新的方法和属性。
2 父类到子类是从一般到特殊的关系。
3 继承用关键字extends
dog extends Animal :表示狗类继承了动物类
4 Java中只允许单继承(java简单性的体现)
父子类之间的关系是树状关系。(而多继承是网状关系)
5 父类中的私有属性可以继承但是不能访问。
也可以说父类中的私有属性子类不能继承。
6 原则:父类放共性,子类放个性。
7 构造方法不能被子类继承。
父类的成员能否继承到子类?
private:本类内部可以访问 不能继承到子类
(default):本类内部可以访问,同包其他类也可以访问
能否继承到子类? 不一定:同包的可继承,不同包则不可继承。
protected:本类内部可以访问,不同包的子类也可以访问, 同包其他类也可以访问
能继承到子类
public:任何地方都可以访问 能继承到子类
继承的意义:
1. 避免了重复的程序代码,提高了程序的可重用性
2. 定义出共同的协议
二、带继承关系的对象创建的过程
1.递归的构造父类对象
2.分配空间
3.初始化属性
4.调用本类的构造方法
三、super 关键字
1.super()表示调用父类的构造方法
2.super()也和this一样必须放在构造方法的第一行第一句。不是构造方法则不用第一行。
3.super.表示调用父类的方法或属性。例:super.m();
4.super 可以屏蔽子类属性和父类属性重名时带来的冲突
5.在子类的构造函数中如果没有指定调用父类的哪一个构造方法,就会调用父类的无参构造方法,即super()
指向父类的引用
super.age
super.addAge()
调用父类的构造方法
super();
super(“wangcai”,8);
一个对象的创建过程
1. 当构造一个对象的时候,系统先构造父类对象,再构造子类对象。
2. 构造一个对象的顺序:(注意:构造父类对象的时候也是这几步)
递归地创建父类的 static 成员(即使只调用其子类静态成员,也会先创建父类静态成员);
顺序地创建本类的 static 成员(只要调用这个类的属性或方法都需创建一次);
递归地创建父类对象(先创建父类非静态成员,再调用父类构造方法);
顺序地创建本类非静态成员(包括属性和方法);
调用本类的构造方法(它可调用本类或父类的成员,也可调用本类的其他构造方法)。
创建完成了(更多详情参看下面:类加载的顺序)
四、白箱复用和黑箱复用
1.白箱复用:又叫继承复用,子类会继承父类所有的东西,
从某种程度上说白箱复用破坏了封装。是一种 is a 的关系。
例:class Liucy{
public void teachCpp(){System.out.println("Teach Cpp");}
public void chimogu(){ }
}
class Huxy extends Liucy{}
2、黑箱复用:又叫组合复用,是一种 has a 的关系。
例:class Liucy{
public void teachCpp(){System.out.println("Teach Cpp");}
public void chimogu(){ }
}
class Huxy {
private Liucy liucy = new Liucy();
public void teachCpp(){liucy.teachCpp();}
}
原则:组合复用取代继承复用原则。
使我们可以有机会选择该复用的功能。
多态
1.定义:是指一个对象可以有多种形态,换句话说多态使我们可以把一个子类对象看作是一个父类对象类型
(例:father A = new child() )。
多态指的是编译时的类型变化,而运行时类型不变。
2.多态分为两种:编译时多态和运行时多态。
编译时类型:定义时类型(主观概念)把它看作什么。
运行时类型:真实类型(客观概念) 实际上他是什么。
重载是编译时多态,覆盖是运行时多态。在方法重载的情况下,参数类型决定于编译时类型。
3.作用:在需要一类对象的共性时,可以很容易的抽取。并且可以屏蔽不同子类对象之间所不关心的差异。
多态方便写出更通用的代码,以适应需求的不断变化
4.多态常见的用法:
(1)、多态用在方法的参数上
(2)、多态用在方法的返回类型上
5.运行时多态的三原则:
(1)、对象不变(改变的是主观认识)
(2)、对于对象的调用只能限于编译时类型的方法。
(3)、在程序的运行时,动态类型判定。运行时调用运行时类型,即他调用覆盖后的方法。
注意:多态时,只有一般方法是动态调用的;而 static 方法和 final 方法依然是静态调用的;属性全是静态调用的。
如:father A = new child(); 则A的一般方法是child的方法;但A的属性是father的属性。
同样:child C = new child(); 则 (father)C 的一般方法还是child的方法,但属性是father的属性。
if(cat instanceof Animal){ ... } //如果cat属于Animal类型则执行
强制类型转换,在迫不得已的时候再用。因为很容易出错。
第八章:高级语言特性
静态变量 static
一个类只有一个静态变量,跟对象没有关系。被类的所有实例共享;如果子类没有覆盖,也共享父类的静态成员。
一般直接使用类名来访问 “类名.静态变量名”。可以在没有任何实例时调用。
在某种意义上类似于全局变量(Java里没有全局变量,这只是C和C++的说法)
不能在 static 方法或代码块里访问非 static 成员(变量或方法)
能继承和覆盖,但覆盖 static 方法必须也是 static 的方法。
1.可以修饰属性、方法、初始代码块,成为类变量、静态方法、静态初始化代码块。
注:初始代码块是在类中而不是在任何方法之内的代码块。
2.类变量、静态方法、静态初始化代码块与具体的某个对象无关,只与类相关,是全类公有的。 在类加载时初始化。
3.类加载:JVM通过CLASSPATH找到字节码文件,并将字节码文件中的内容通过I/O流读到JVM并保存的过程
在虚拟机的生命周期中一个类只被加载一次。
注:Java命令的作用是启动JVM (Java Virtual Mechine)。
4.tatic 定义的是一块为整个类共有的一块存储区域,其发生变化时访问到的数据都是经过变化的。
5.为什么主方法必须是静态的?
主方法是整个应用程序的入口,JVM只能通过类名去调用主方法。
6.类变量和静态方法可以在没有对象的情况下用:类名.方法名(或属性名)来访问。
7.静态方法不可被覆盖(允许在子类中定义同名的静态方法,但是没有多态)
父类如果是静态方法,子类不能覆盖为非静态方法。父类如果是非静态方法,子类不能覆盖为静态方法。
争论:静态方法可以覆盖但是没有多态。
思考:没有多态的覆盖叫覆盖吗?
在静态方法中不允许调用本类中的非静态成员。
8.静态初始化代码块只在类加载的时候运行一次,以再也不执行了。所以静态代码块一般被用来初始化静态成员。
9.不加static为动态初始化代码块,在创建对象时被调用(在构造函数之前)。
10.最后要注意的一点就是 static 不能修饰局部变量。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -