1.抽象类的定义:在class前面添加abstract关键字就行。
2.抽象类是无法实例化的,无法创建对象,所以抽象类是用来被子类继承的。
3.final和abstract是不能联合使用,这两个关键字对立。
4.抽象类的子类是可以抽象类的,也可以是非抽象类的。
5.抽象类虽然无法实例化,但是抽象类有构造方法,这个构造方法是供子类使用的。
6.抽象类不一定有抽象方法,抽象方法必须出现在抽象类中。
7.抽象方法定义:public abstract void doSome();
8.【重点】一个非抽象的类,继承抽象类,必须将抽象类中的抽象方法进行覆盖。
不对,错误的。Object类就有很多没有方法体,都是以";"结尾的,但他们都不是抽象方法。例如:public native int hashCode();这个方法底层调用了C++写的动态链接库程序。前面修饰符列表中没有abstract。有一个native,表示调用JVM本地程序。
1.接口也是一种引用数据类型。
2.接口是完全抽象类。(抽象类是半抽象类)或者说接口是特殊的抽象类。
3.接口的定义:[修饰符列表] interface 接口名{}
4.接口支持多继承,一个接口可以继承多个接口。
5.接口中只包含两部分内容,一部分是常量,一部分是抽象方法。接口中没有其他内容了。
6.接口中所有的元素都是public修饰的。(都是公开的)
7.接口中的抽象方法定义时:public abstrct修饰符可以省略。
8.接口常量的public static final可以省略。
9.接口中的方法都是抽象方法,所以接口中的方法不能有方法体。
10.【重点】一个非抽象类实现接口的时候,必须将接口中的所有方法加以实现(覆盖/重写)。
11.一个类可以实现多个接口。
12.extends和implements可以共存,extends在前,implements在后。
13.使用接口,写代码的时候,可以使用多态(父类型引用指向子类型对象)
对于计算机来说,一个机箱有多个接口,一个接口是接键盘的,一个接口是接鼠标的,一个接口是接电源的,一个接口是接显示器的…所以【重点】一个类可以同时实现多个接口。
这种机制弥补了java中哪个缺陷??
java中类和类支持单继承,实际上单继承是为了简单而出现的,显示世界中存在多继承,java中的接口弥补了单继承带来的缺陷。
接口和接口之间进行强制类型转换的时候,没有继承关系,也可以强转。但是一定要注意,运行时可能会出现ClassCastException异常。
之前有个结论:无论是向上转型还是向下转型,两种类型之间必须要有继承关系。没有继承关系编译器会报错。(这句话不使用在接口方面)最终实际上和之前还是一样的,需要加instanceof运算符进行判断向下转型养成好习惯。转型之前先if+instanceof判断。
接口在开发中的作用类似于多态在开发中的作用。
多态:面向抽象编程,不要面向具体编程。降低程序的耦合度,提高程序的扩展力,符合OCP开发原则(对扩展开发,对修改关闭)。
有了接口就有了可插拔,可插拔表示扩展能力很强,不是焊接死的。
is a(继承)、has a(关联)、like a(实现)
is a:Cat is a Animal(猫是一种动物)凡是能够满足is a表示“继承关系” :A extends B。
has a:I has a pen(我有一只笔)凡是能够满足has a关系的表示“关联关系”,关联关系通常以“属性”的形式存在:A { B b;}
like a:Cooker like a FoodMenu(厨师像一个菜单一样)凡是能够满足like a关系的表示“实现关系”,实现关系通常是类实现接口:A implements B。
在这里只说一下抽象类和接口在语法上的区别。
1.抽象类是半抽象的,接口是完全抽象的。
2.抽象类中有构造方法,接口中没有构造方法。
3.接口和接口之间支持多继承,类和类之间只能单继承。
4.一个类可以同时实现多个接口,一个抽象类只能继承一个类(单继承)。
5.接口中只允许出现常量和抽象方法。
A类中使用B类。
A和B类都在同一个包下,不需要import。
A和B类不在同一个包下,需要使用import。
java.lang.*这个包下的类不需要import导入。
API是应用程序编程接口(Application Program Interface)。
整个JDK的类库就是一个javaSE的API。
每一个API都会配置一套API帮助文档。
SUN公司提前写好的这套类库就是API。
1.Object这个类当中有哪些常用的方法?
protected Object clone()//负责对象克隆
int hashCode()//获取对象的哈希值
boolean equals(Object obj)//判断两个对象是否相等
String toString()//将对象转换成字符串形式
protected void finalize()//垃圾回收器负责调用的方法
2.关于Object类中的toString()方法
toString()方法的作用:通过调用这个方法将一个“java对象”转换成字符串表达形式。
SUN公司在开发java语言的时候,建议所有的子类都去重写toString()方法,toString()方法应该是一个简洁的、详实的、易阅读的。
System.out.println(引用);这里会自动调用引用的toString()方法。
String类已经重写了toString()方法
class MyTime{
private int year;
private int month;
private int day;
public MyTime(){
}
public MyTime(int year, int month, int day){
this.year=year;
this.month=month;
this.day=day;
}
public String toString(){
return this.year+"年"+this.month+"月"+this.day+"日";
}
}
//注意:输出引用的时候,会自动调用该引用的toString方法
MyTime t1 = new MyTime(1970,10,10);
System.out.println(t1);
3.关于Object类中的equals方法
equals方法的源码:
public boolean equals(Object obj){
return (this==obj);
}
以上这个方法是Object类的默认实现。
equals方法的目的:在以后的编程过程中,杜勇通过equals方法来判断两个对象是否相等。
java中基本数据类型比较是否相等,使用“==”
java中所有的引用数据类型统一使用equals方法来判断是否相等。
在Object类中的equals方法当中,默认采用的是“==”判断两个对象是否相等,而“==”判断的是两个java对象的内存地址,我们应该判断两个java对象的内容是否相等。所以Object的equals方法不够用,需要子类重写equals方法。
String类已经重写了equals方法,比较两个字符串不能使用“==”,必须使用equals。
注意:重写equals方法的时候一定要重写彻底。
4.关于Object类的finalize方法
在Object类中的源代码:
protected void finalize() throws Throwable{}
GC:负责调用finalize方法。
这个方法不需要程序员手动调用,JVM垃圾回收器负责调用这个方法。
finalize方法的执行时机:当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize方法。
finalize方法实际上是SUN公司为java程序员准备的一个时机,垃圾销毁时机。
如果希望在对象销毁时机,执行一段代码,这段代码要写到finalize方法当中。
比如在项目开发中有这样一个业务:所有对象在JVM中释放的时候,请记录一下释放的时间。那么这个记录对象的代码就需要写到finalize方法里面。
注意:java中的垃圾回收器不是轻易启动的,垃圾太少或者时间没到等种种原因,有可能启动,也有可能不启动。
System.gc();//建议启动垃圾回收器。(只是建议,可能不启动,也有可能启动)
5.关于Object中的hashCode方法
源码:public native int hashCode();
这个方法不是抽象方法,带有native关键字,底层调用C++程序。
hashCode方法返回的是哈希码,实际上就是一个java对象的内存地址,经过哈希算法,得出一个值。所以hashCode方法的执行结果可以等同看做一个java对象的内存地址。
什么是内部类?
内部类:在类的内部又定义了一个新的类,被称为内部类。
内部类的分类:
静态内部类:类似于静态变量
实例内部类:类似于实例变量
局部内部类:类似于局部变量
使用内部类编写的代码,可读性很差,能不用尽量不用。
匿名内部类是局部内部类的一种,因为这个类没有名字而得名。
匿名内部类有两个缺点:
缺点1:太复杂,太乱,可读性差
缺点2:类没有名字,以后想重复使用,不能用。