1.权限修饰符(掌握)
注:这四种权限修饰符在任意时刻只能出现一种
- 分类:
权限修饰符:private,默认,protected,public
状态修饰符:static,final
抽象修饰符:abstract - 类及其组成可以用的修饰符
常用的组合:
public static final int X = 10; //静态、常量
public static void show() {} //静态方法
public final void show() {} //最终的方法
public abstract void show(); //抽象方法
2.内部类(理解)
- 概述:把类定义在另一个类的内部,该类就被称为内部类
例,把类B定义在类A中,类B就被称为内部类 - 内部类的访问规则:
- 可以直接访问外部类的成员,包括私有
- 外部类要想访问内部类的成员,必须创建对象
- 分类(按位置对内部类):
- 在成员位置:成员内部类
- 在局部位置(也就是在方法内):局部内部类
3.成员内部类
-
外界如何创建对象
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer.Inner oi = new Outer().new Inner(); -
常见修饰符 //但,这两个修饰符正常不会同时修饰
-
private:为了保证数据的安全性
-
static:为了让数据访问更方便
a:成员内部类被静态修饰后,只能访问外部类的静态成员
b:成员内部类被静态修饰后,里面可以定义静态方法,也可以定义非静态方法
c:成员内部类被静态修饰后,外界如何创建对象的格式是:外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner(); -
面试题:请填空,分别输出30,20,10
class Outer { public int num = 10; class Inner { public int num = 20; public void show() { int num = 30; System.out.println(num); System.out.println(this.num); //System.out.println(new Outer().num); //可以,但不够好 System.out.println(Outer.this.num); //改进版 } } } class InnerClassTest { public static void main(String[] args) { Outer.Inner oi = new Outer().new Inner(); oi.show(); } }
4.局部内部类
-
可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
-
面试题:
-
局部内部类访问局部变量的注意事项:
局部变量必须被fianl修饰原因:
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值
5.匿名内部类(掌握)
- 概述:就是内部类的简化写法
- 前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类
- 格式:new 类名或者接口名() {重写方法;}
所以它的本质并不是一个类,而是一个继承了该类或者实现了该接口的,子类匿名对象
interface Inter {
public abstract void show();
public abstract void show2();
}
class Outer {
public void method() {
//一个方法的时候
/*
new Inter() {
public void show() {
System.out.println("show");
}
}.show(); //注意这里的格式
*/
//二个方法的时候
/*
new Inter() {
public void show() {
System.out.println("show");
}
public void show2() {
System.out.println("show2");
}
}.show();
new Inter() {
public void show() {
System.out.println("show");
}
public void show2() {
System.out.println("show2");
}
}.show2();
*/
//如果我是很多个方法,就很麻烦了
//那么,我们有没有改进的方案呢?
Inter i = new Inter() { //多态
public void show() {
System.out.println("show");
}
public void show2() {
System.out.println("show2");
}
};
i.show();
i.show2();
}
}
class InnerClassDemo6 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
- 在开发中的应用:
interface Person {
public abstract void study();
}
class PersonDemo {
//接口名作为形式参数
//其实这里需要的不是接口,而是该接口的实现类的对象
public void method(Person p) {
p.study();
}
}
//实现类
/*开发中,使用匿名内部类就不用多建这个实现类了
class Student implements Person {
public void study() {
System.out.println("好好学习,天天向上");
}
}
*/
class InnerClassTest2 {
public static void main(String[] args) {
//测试
PersonDemo pd = new PersonDemo();
Person p = new Student();
pd.method(p);
System.out.println("--------------------");
//匿名内部类在开发中的使用(适合用的次数少的时候,次数多还是建个类方便)
//匿名内部类的本质是继承类或者实现了接口的子类匿名对象
pd.method(new Person(){
public void study() {
System.out.println("好好学习,天天向上");
}
});
}
}
- 面试题:
按要求补齐代码:2019-08-20Inner
按要求,补齐代码
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”
分析:
Outer.method()可以看出method()应该是Outer中的一个静态方法
Outer.method().show()可以看出method()方法的返回值是一个对象
又由于接口Inter中有一个show()方法,所以method()方法的返回值类型是一个接口
class Outer {
//补齐代码
public static Inter method() {
//子类对象 -- 子类匿名对象
return new Inter() {
public void show() {
System.out.println("HelloWorld");
}
};
}
}