p407-429
接口
一个类可以实现多个接口(电脑上可以有很多插口)
class computer IB,IC{}
接口中的属性只能是final,并且是public static final
接口不能继承其他类,但是可以继承多个别的接口
interface ID extends IB,IC{}
接口的修饰符只能是默认或者public
接口和继承
接口感觉就是实现多继承啊,利用接口来学习。接口就是对单继承机制的补充。
class LittleMonkey extends Monkey implements Fishable,Birdable { }
父子关系和师徒关系,接口更灵活。
解耦:即接口规范性+动态绑定
接口的多态特性
用接口作为形参,传进来的是对象实例。相当于向上转型。
当需要调用特有的功能时:
可以通过向下转型来调用。
接口的多态传递
接口类型的变量可以指向实现了该接口的类对象的实例
接口是可以继承的。这里IG继承了IH接口,而Teacher类实现了IG接口,相当于Teacher类也实现了IH接口。
课堂练习
跑了一下失败了,相当于接口里的【public static final int x =0】和父类的x冲突了。(它们是同级的?)
当我要访问接口中的x可以用A.x,当我访问父类的x就用super.x
内部类(重点)
一个类的内部,又完整嵌套了另一个类的结构,被嵌套的类成为内部类(inner class)
嵌套其他的类被称为外部类(outer class)。
跟他们没关系的类就是外部其他类
注意:类的五大成员
1.属性
2.方法
3.构造器
4.代码块
5.内部类
内部类的最大特点:可以直接访问私有属性,并且可以体现类之间的包含关系。
内部类可以无限套娃。
内部类有四种:
1.局部内部类
1.可以直接访问外部类的所有成员,包含私有的
2.不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用访问修饰符的。但是可以使用final,因为局部变量也可以final
3.作用域:仅仅在定义它的方法或者代码块中
4.局部内部类--访问-->外部类的成员【访问方式:直接访问】
5.外部类--访问-->局部内部类的成员【访问方式:创建对象,再访问。注意要在作用域内,也就是说,外部类在方法中创建内部类,再调用】
记住:局部内部类是定义在方法或者代码块中,它的作用域在方法体或者代码块,本质仍然是个类
6.外部其他类不能访问局部内部类
7.如果外部类和局部内部类的成员重名时,遵守就近原则。如果要调用外部类的变量,使用类名.this.成员名。
比如:
public class Outer{
private int n1 = 1;
class Inner{
private int n1 =2;
public void f1(){
sout(“n1=”+n1+“外部类的n1=”+Outer.this.n1);
}
}
}
注意,这里的Outer.this本质是外部类的对象,即哪个对象调用了f1方法,那么this就指向了哪个对象
2.匿名内部类(anonymous,重要!!!)
匿名内部类就是定义在外部类的局部位置,比如方法中,并且没有类名。本质:1.是类,2.定义在外部类的局部 3.该类没有名字(其实有名字,但是是系统给分配的,我看不到)。4.匿名内部类同时还是个对象。
语法:
new 类或接口(参数列表){
类体
};
记得加分号!!
基于接口的匿名内部类
这里的tiger的编译类型是IA接口,运行类型就是匿名内部类!
底层:class XXXX implements IA{
实现接口方法}
这儿XXXX的名称是
类名中的$就是系统分配的类名。
匿名内部类使用一次,就不能再使用。但是这个对象里的方法可以一直调用哈!(类没了,对象还在...时间过去了,照片还在?)
基于类的匿名内部类
new Father(){};加上这个大括号就不一样了!
这个f的编译类型是Father,但是运行类型是Feiju$1
注:如果是基于抽象类的匿名内部类,需要实现那些抽象方法
细节
1.动态绑定机制
2.即是个类也是个对象,可以直接调用
这里甚至能直接调用
3.不能添加访问修饰符
4.作用域在方法或者代码块之中
5.外部其他类不能访问匿名内部类
6.如果外部类的成员和匿名内部类的成员重名时,匿名内部类访问的话遵从就近原则,如果想访问外部类的成员,则可以使用(外部类名。this。成员)去访问。
匿名内部类使用
把匿名内部类当做实参传递
记得打分号。再f1的参数列表里直接new
3.成员内部类
成员内部类是定义在外部类的成员位置,并且没有static修饰的。(否则就是静态内部类)
1.可以直接访问外部类的所有成员
2.可以添加任意的访问修饰符(public、默认、protected、private),毕竟它是个成员
3作用域:和外部类的其他成员一样,为整个类体。
4成员内部类访问外部类是直接访问的
5外部类访问内部类是创建对象再访问
6外部其他类访问
6.1外部类的对象去new一个内部类实例:相当于把new Inner08()当做是Outer08的成员
6.2在外部类中,编写一个方法来返回内部类
7.如果外部类和内部类的成员重名了,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
4.静态内部类
静态内部类是定义在外部类的成员位置,并且有static修饰
1.可以直接访问外部类的所有静态成员,包括私有的。但是不能直接访问非静态成员!
2.可以添加任意访问修饰符,因为它的地位就是一个成员。
3.作用域:和其他成员一样,为整个类体
4.可以通过外部类名直接访问,需要满足访问权限
例:
注意:重名了不用加this了,因为静态内部类也只能访问外部的静态属性,这种属性直接类名调用
到这里面向对象就讲完了
枚举类
1.枚举是一组常量的集合
2.枚举属于一种特殊的类,里面只包含一组有限的特定对象
static+final不会导致类加载!
使用enum关键字实现枚举类
1.使用关键字enum替代class
2.public static final Enu1 SPRING = new Enu1(“春天”,“温暖”);改成
SPRING(“春天”,“温暖”);
即 常量名(实参列表)
3.如果有多个常量对象,使用逗号间隔:
SPRING(“春天”,“温暖”),SUMMER(“夏天”,“热”);
4.如果使用enum来实现枚举,要求定义常量对象,写在最前面。
enum关键字注意事项
javap指令:反编译。
1当我们使用enum关键字来开发一个枚举类时,默认会final继承Enum类。使用javap工具来证明
Enum类的toString方法是return name
2.传统的public static final Season2 SPRING = new Season2(“春天”,“温暖”)简化成
SPRING(“春天”,“温暖”),这里必须知道,它调用的是哪个构造器
3如果使用无参构造器创建创建枚举对象,则实参列表和小括号都可以省略。
4.当有多个枚举对象时,使用逗号间隔。
5.枚举必须放在行首