上一节讲的是封装与继承,本章将来简单说一下final,abstract,Object,类与类之间的关系,内部类以及设计模式。
1.final
final关键字是终止的最后的意思,修饰符
①final修饰的变量只能被赋值一次,
②final修饰的类不能被继承,
③final修饰的方法不能被重写
注意:final修饰引用类型的变量,值确实不能被修改,但引用类型的变量存储的是地址值,所以对象里面的属性可以操作,并且地址值也并没有被修改地址值并没有改。
2.abstract
abstract关键字,抽象的,修饰符
可以用来修饰类,方法
修饰类时,表示为抽象类,抽象类用于被继承,抽象类不可以实例化,抽象类可以有抽象方法也可以没有抽象方法,抽象类的子类必须要重写父类的所有抽象方法,否则该子类要是抽象类,且抽象子类对方法覆写数量无要求
修饰方法时,表示为抽象方法,抽象方法没有方法体,主要是定义功能,实现由其子类覆写,抽象方法所在的类一定是抽象类,不然报错,
3.interface
interface关键字,用于定义接口,接口里面的变量只能是常量,
接口与类之间是实现关系,而且是多实现关系
接口的属性方法默认public 修饰,接口不能被实例化,没有构造方法,但可以实现多态
接口与接口之间是继承关系可以多继承,抽象类实现接口,非必要全部实现抽象方法,但是子类实现接口时需要实现接口的所有抽象方法
jdk1.8之前的接口只有抽象方法和常量,1.8之后接口可以定义静态与默认方法
当抽象类和接口都可以实现某个功能时,优先使用接口,因为类和接口之间是多实现关系,使用接口后留下了类继承,易扩展
4.Object
所有类的根类,都直接或间接的继承了此类,该类所在的包是java自带的核心包
4.1.equals
equals方法被设计用于比较两个对象是否相等,但其默认比较引用类型变量的地址值是否相同(是否指向同一内存),因为每个对象的属性都不一样。
但是某些类,比如String类中会重写此方法以比较值是否相同。
==比较基本类型的值,比较引用类型的地址值。
4.2.Finalize
此方法在垃圾回收时被调用,但此方法并不具备回收机制。
4.3.toString
此方法用于返回字符类型的变量值,便于展示,且其默认返回引用类型变量的地址。
5.类与类之间的关系
①继承 extends ②实现 implements
③依赖关系,局部变量为另一个类的引用
④关联,成员或静态变量为另一个类的引用
⑤聚合,成员变量与局部变量都存在,有各自的生命周期,整体与部分的关系
⑥组合,特殊的关联关系,整体的声明周期开始,局部的生命周期也开始,整体结束,局部随之结束
public class ClassRelationship {
// 关联关系
private A a;
// 组合关系
public ClassRelationship() {
a = new A();
}
public static void main(String[] args) {
// 依赖关系
B b;
}
// 聚合关系
public void m(A a) {
this.a = a;
}
}
//继承
class A extends B {
}
//实现
class B implements C {
}
interface C {
}
6.内部类
当一个类中需要一个完整结构的其他类,并且此类只服务于所属的外部类时便可以定义内部类
分为静态内部类,成员内部类,局部内部类,匿名内部类
静态内部类--static修饰的内部类
静态内部类不能直接访问外部类的成员属性
成员内部类--非static修饰的内部类
成员内部类里面不能有静态声明,可以直接访问外部类的属性
//成员内部类的声明
OuterClass oc=new OuterClass();
InnerClass ic=oc.new InnerClass();
//静态内部类的声明
InnerClass1 ic1=new OuterClass.InnerClass1();
局部内部类--定义在方法中的内部类
- 成员方法中的局部内部类里面不能有静态声明,可以直接访问外部类的成员属性,且其不能用权限修饰符与static修饰
- 静态方法中的局部内部类,不能直接访问外部类的成员属性
- 局部内部类只能在其所在的方法内使用
public class LocalInnerClass {
private int age;
public void m1() {
class InnerClass{
int age1;
public void im1() {
System.out.print(age);
}
}
}
public static void m2() {
class InnerClass{
int age1;
public void im1() {
LocalInnerClass lic=new LocalInnerClass();
System.out.print(lic.age);
}
}
InnerClass ic=new InnerClass();
ic.im1();
}
}
匿名内部类--没有名字的内部类(重要)
匿名内部类为了简化代码,可以用于参数为类对象的方法时,参数写为匿名内部类
匿名内部类可以作为方法的实际参数进行传输
匿名内部类创建的数据类型是new的类的子类
public class AnonymousInnerClass {
public static void main(String[] args) {
Cat cat=new Cat();
AnonymousInnerClass aic=new AnonymousInnerClass();
aic.m2(cat);
aic.m2(new Animal() {
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("匿名内部类");
}
});
}
public void m2(Animal animal) {
animal.eat();
}
}
class Cat implements Animal {
@Override
public void eat() {
System.out.println("猫要吃肉");
}
}
interface Animal {
void eat();
}
7.设计模式
设计模式,软件设计模式,是被反复使用过的,多数人知晓的代码经验的总结
优点:代码复用,易于理解,程序重用
单例模式是其中一种,分为懒汉模式与饿汉模式
饿汉模式是类加载时就创建好一个对象,而懒汉模式是首次访问时才被创建
public class Singleten {
// 饿汉模式,类加载时对象就创建完成
public static Singleten sin=new Singleten();
// 懒汉模式,使用对象时再创建
public static Singleten s;
public static Singleten getObject() {
if (s == null)
s = new Singleten();
return s;
}
private Singleten() {
}
}
注意:abstract与final不能同时出现