接口
接口概念 好处是一种规范,不给实现 分离 定义
java单继承,通过继承可以实现多继承1
2
3
4
5
6
7
8//接口不是类,不能用new实例化一个接口 X = new Test; error
public interface Test {
//接口不能包含实例域,但可以定义常量,默认public static final,省略
int id = 10;
/*接口中的方法自动属于public,可省略关键字public
接口中的方法均为抽象方法,省略abstract */
void Method01();
}接口的实现 implements
- 一个类可以实现多个接口:Teacher类实现了Singer、Painter接口
- 多个无关的类可以实现同一个接口:Student类、Teacher类都实现了Singer接口
- 多态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47interface Painter { //Painter接口
void eat(); //两个抽象方法
void paint();
}
interface Singer { //Singer接口
void sing(); //两个抽象方法
void sleep();
}
class Student implements Singer {
public void sing() { //实现接口中的sing方法
System.out.println("Student is singing;");
}
public void sleep() { //实现接口中的sleep方法
System.out.println("Student is sleeping;");
}
}
class Teacher implements Singer,Painter {
public void eat() {
System.out.println("Teacher is eating;");
}
public void paint() {
System.out.println("Teacher is painting;");
}
public void sing() {
System.out.println("Teacher is singing;");
}
public void sleep() {
System.out.println("Teacher is sleeping;");
}
}
public class InterfaceTest {
public static void main(String[] args) {
Singer s1 = new Student();
s1.sing();
s1.sleep();
Singer s2 = new Teacher();
s2.sing();
s2.sleep();
Painter p1 = (Painter)s2;
p1.eat();
p1.paint();
}
}
画内存图
- 接口与抽象类
Lambda表达式
内部类
- 内部类:定义在另一个类中的类;为什么使用内部类?
- 内部类中的方法可以访问外部类的所有成员属性和方法,包括私有数据
- 内部类可以对同一个包中的其他类隐藏起来
- 当想要定义一个回调函数且不想编写代码时,使用匿名内部类更加便捷
成员内部类:最普通的内部类,与外部类的成员变量和方法并列,相当于外部类的一个成员,外部类要访问内部类的成员属性和方法则需要通过构造内部类实例来访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/*在编译时,编译器将内部类翻译成用$分隔外部类与内部类名的常规类文件(两个.class文件:
OuterClass.class、OuterClass$InnerClass),内部类的对象总有一个隐式引用,
它指向了创建它的外部类对象 */
public class OuterClass {
private String str; //外部类私有属性
public void outerInfo() {
System.out.println("outerClass");
}
public class InnerClass { //内部类
public void innerInfo() {
str = "Litsao"; //内部类直接调用外部类私有属性
System.out.println(str);
outerInfo(); //内部类直接调用外部类方法
}
}
public static void main(String[] args) {
//外部类实例化:外部类 对象1 = new 外部类();
OuterClass outer = new OuterClass();
/*成员内部类是依附于外部类的,所以只有先创建了外部类才能够创建内部类
*内部类实例化:外部类.内部类 对象2 = 对象1.new 内部类();
*/
OuterClass.InnerClass inner = outer.new InnerClass();
inner.innerInfo(); //构造内部类实例后才能访问内部类的成员变量/方法
}
}局部内部类:内部类定义在外部类的方法中,内部类的作用域只在方法内部
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32public class LocalInnerClass {
public static void main(String[] args){
Outer outer = new Outer();
//外部类对象通过其方法调用内部类,方法结束局部内部类的对象也就释放了
outer.showOuter();
}
}
class Outer {
private int num1 = 10;
private static int num2 = 20;
public void showOuter(){
final int num3 = 50;
//局部内部类不是类成员,放在方法内部,前面不能有修饰符
class Inner {
private int num1 = 20;
private int num2 = 30;
public void showInner() {
System.out.println("内部类num1:" + num1); //20,打印内部类的num1、num2
System.out.println("内部类num2:" + num2); //30
//局部内部类访问外部类成员:外部类.this.成员
System.out.println("外部类num1" + Outer.this.num1); //10,打印外部类的num1
System.out.println("外部类静态变量:" + num2);
//局部内部类访问作用域内的局部变量,该局部变量需要使用final修饰
System.out.println("作用域内局部变量:" + num3);
}
}
//局部内部类的对象需在内部类编译后再创建
//局部内部类对于外界是隐藏的,因此需要在内部类里面完成对象的定义和引用
Inner inner=new Inner();
inner.showInner();
}
}匿名内部类:特殊的局部内部类,没有名字,只使用一次
1
2静态内部类:使用static修饰的内部类(嵌套内部类)
非静态内部类不能包含static成员?1
2