0. 理解面向对象.
- 早期的思想是面向过程, 而现在的面向对象思想是相对于面向过程而言的.
- * 面向过程, 强调的功能行为. 面向对象, 将功能封装进对象, 强调具备了功能的对象.
- * 面向对象是基于面向过程的.
- * 面向过程到面向对象, 是从执行者到指挥者的转变.
- Everything is an Object.
1. 面向对象开发: 其实就是不断的创建对象, 使用对象, 指挥对象做事情.
2. 面向对象设计: 其实就是管理和维护对象之间的关系.
3.* 面向对象的特征:
- 封装(encapsulation): 指隐藏对象的属性和实现细节, 仅对外提供公共访问方式.
好处: 将变化隔离; 便于使用; 提高重用性; 提高安全性.
封装原则: 将不需要对外提供的内容都隐藏起来; 把属性都隐藏, 提供公共方法对其访问. - 继承(inheritance): 多个类中存在相同属性和行为时,就将这些内容抽取到单独一个类中, 那么多个类无需再定义这些属性和行 为,只要继承单独的那个类即可.
好处: 继承的出现提高了代码的复用性. 继承的出现让类与类之间产生了关系, 提供了多态的前提.
* 注意: Java只支持单继承. 但是接口对接口之间不是用实现(implements), 也是用继承(extends), 此时可以多继承. - ** 多态(polymorphism): 可以理解为事物存在的多种体现形态(不只对象有多态性, 函数的重载也是多态性的体现).
体现: 父类或者接口的引用指向或者接受自己的子类对象.
好处: 多态的出现大大提高程序的扩展性.
弊端: 提高了扩展性, 但是只能使用父类的引用访问父类中的成员.
作用: 多态的存在提高了程序的扩展性和后期的可维护性.
前提: 需要存在继承或者实现关系; 要有覆盖操作.
特点:
(非静态)成员函数: 编译时, 要查看引用变量所属的类中是否有所调用的成员; 运行时, 要查看对象所属的类中是否有所调用的成员. (编译时看左边, 运行时看右边.)
* 成员变量: 无论编译和运行, 只看引用变量所属的类(左边).
静态成员函数: 无论编译和运行, 只看引用变量所属的类(左边).
4. 成员变量 VS 局部变量.
- 成员变量定义在类中, 在整个类中都可以被访问. 成员变量随着对象的建立而建立, 存在于对象所在的堆内存中.* 成员变量有默认初初始化值.
- 局部变量只定义在局部范围内(函数内、语句内等). 局部变量存在于栈内存中, 作用范围结束后, 变量空间自动释放.* 局部变量没有默认初始化值.
- 作用: 给对象进行初始化.
- * 对象一旦建立就执行, 优先于构造函数执行.
- 和构造函数的区别: 构造代码块是给所有对象进行统一初始化, 而构造函数是给对应的对象初始化.
6.* this关键字.
- 特点: this代表其所在函数所属对象的引用. 换言之, this代表类对象的引用.
- 使用情景: 当函数内需要用到调用该函数的对象时, 就用this.
- 静态方法中不能写this、super关键字.
7.* this关键字在构造函数间的调用. (内部名称: this语句).
class Person
{
private String name;
private int age;
Person(String name)
{
this.name = name;
}
Person(String name, int age)
{
//this.name = name;
//this语句. 直接用this调用Person(String name)构造函数. 因为this代表一个对象, 所以this(name)就相当于new Person(name).
this(name);
this.age = age;
}
}
8.* this语句只能写在构造器的第一行. super也是.
9.* super和this的用法几乎相同.this代表本类对象的引用, super代表父类对象的引用.
super也有super语句(自己起的名字..), 调用父类构造器.
如果子类中出现非私有的同名成员变量时, 子类要访问本类中的变量, 用this; 子类要访问父类中的同名变量, 用super.
class Fu
{
int num = 4;
}
class Zi extends Fu
{
int num = 5;
void show()
{
System.out.println(this.num); //this可以省略
System.out.println(super.num);
}
}
10. 被static(静态)关键字修饰的成员(成员变量和成员函数).
- 随着类的加载而加载.
- 优先于对象存在.
- 被所有对象所共享.
- 可以直接被类名调用.
13. 静态代码块.
static
{
...
}
用于对类进行初始化, 随类的加载而执行, 且只执行一次.
14.* 单例设计模式: 使一个类在内存中只存在一个对象.
class Single //饿汉式
{
private Single(){}
private static Single s = new Single();
public static Single getInstance()
{
return s;
}
}
class Single_2 //懒汉式, 延迟加载.
{
private Single_2(){}
private static Single_2 s = null;
public static Single_2 getInstance()
{
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s = new Single_2();
}
}
return s;
}
}
饿汉式, 懒汉式.
懒汉式线程不安全, 用synchronized可以解决但是效率变低.
*建议使用懒汉式.
15. 覆盖:
- 子类覆盖父类, 必须保证子类权限大于等于父类权限, 才能覆盖, 否则编译失败.
- 静态只能覆盖静态.
17.** 为什么子类一定要访问父类中的构造函数?
答: 因为父类中的数据子类可以直接获取. 而父类中的数据可能是经过父类构造函数初始化的, 所以在子类使用前必须要经过父类指定构造函数的操作.
18.** 子类必须调用父类的构造方法, 因为父类中的数据子类可以直接获取, 当子类对象初始化时, 如果父类中没有空参数的构造函数时, 子类的所有构造函数必须通过this或者super语句指定要访问的构造函数. (子类的所有的构造函数, 默认都会访问父类中空参数的构造函数, 如果父类没空参的构造函数, 则要手动通过super或者this指定要访问的构造函数).
19. final修饰的作为常量, 书写规范: 所有字母都大写, 由多个单词组成时, 单词间用_连接.
20. 局部内部类只能访问该局部被final修饰的局部变量.
21. 抽象类: java中可以定义没有方法体的方法, 该方法的具体实现由子类完成, 该方法抽象方法. 包含抽象方法的类就是抽象类.
22. 抽象类可以有构造函数, 但是不能被实例化(即使是没有抽象方法的抽象函数).
23.* 模板设计模式: 在定义功能时, 功能的一部分是确定的, 但是有一部分是不去定的. 而确定的部分要使用不确定的部分, 这是就将不确定的部分暴露出去, 由该类的子类去实现.
class GetTime //没有用模板设计模式
{
public void getTime()
{
long start = System.currentTimeMillis();
for(int x=0; x<1000; x++)
{
System.out.print(x);
}
long end = System.currentTimeMillis();
System.out.println("毫秒: " + (end-start));
}
}
abstract class GetTime_2 //模板设计模式.
{
public final void getTime() //该类的功能, 不希望被重写, 所以final.
{
long start = System.currentTimeMillis();
runcode();
long end = System.currentTimeMillis();
System.out.println("毫秒: " + (end-start));
}
public abstract void runcode(); //作为模板, 子类可以通过重写这个方法来获取相应功能.
}
24. 接口(interface)中的成员修饰符是固定的(可以省略).
- * 成员变量: public static final
- 成员函数: public abstract
28. 内部类: 将一个类定义在另一个类里面, 里面那个类就叫内部类.
29. 内部类的访问特点:
- 内部类可以直接访问外部类中的成员,包括私有成员。
- 而外部类要访问内部类中的成员必须要建立内部类的对象。
- 对于严重的, 通过错误(Error)类进行描述; 非严重的, 用异常(Exception)类描述.
- 对于Error一般不编写针对性的代码对其进行处理; 而对Exception可以使用针对性的处理方式进行处理.
- Error和Exception有共性(不正常情况的信息、引发原因等), 对其抽象为Throwable类.
- 编译时被检测的异常 .
- 编译时不被检测的异常(运行时异常. RuntimeException以及其子类).
- 一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。
- 如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常。
38.* 四种访问权限.
39. import用来导包中的类, 不导包中的包.
40. Jar包的操作. 通过jar.exe工具对jar的操作.
- 创建jar包:jar -cvf mypack.jar packa packb
- 查看jar包:jar -tvf mypack.jar [>定向文件]
- 解压缩:jar -xvf mypack.jar
- 自定义jar包的清单文件:jar –cvfm mypack.jar mf.txt packa packb