1.成员内部类
1.1成员内部类的访问特点
-
内部类可以直接访问外部类的成员,包括私有
-
外部类要访问内部类的成员,必须要创建对象
1.1.1应用实例:
需求:写一个javabean类描述一个汽车
属性:品牌,车龄,颜色,发动机的 品牌,使用年限public class Car { String carName; int carAge; String carColor; public void show(){ System.out.println(carName); Engine e = new Engine(); System.out.println(e.engineName); } public class Engine{ String engineName; int engineAge; public void show(){ System.out.println(carName); System.out.println(engineAge); } } } public class Test { public static void main(String[] args) { Car c = new Car(); c.carName = "奔驰"; c.carAge = 10; c.carColor = "黑色"; c.show(); } }
1.3如何创建成员内部类对象?
编写成员内部类的注意点:
1.成员内部类可以被一些修饰符所修饰,比如:private,默认,protected,public,static
获取成员内部类的两种方式:
1.外部类编写方法
对外提供内部类对象(内部类函数被private修饰的时候)
代码实例:
public class Outer { String name; public class Inner{ } //在外部类中定义方法,返回一个内部类对象 public Inner getInstance(){ return new Inner(); } } public class Tset { public static void main(String[] args) { Outer o = new Outer(); //使用了多态,用父类接收子类 Object instance = o.getInstance(); System.out.println(instance); } }
2.直接在Test类中创建内部类对象
格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
范例: Outer.Inner inner = new Outer().new Inner();
public class Outer { String name; public class Inner{ } } public class Tset { public static void main(String[] args) { //外部类名.内部类名 对象名 = 外部类对象.内部类对象; Outer.Inner inner = new Outer().new Inner(); System.out.println(inner); } }
1.4成员内部类如何获取外部类的成员变量?
面试题:
当外部类成员变量和内部类成员变量重名时,在内部类如何访问?
需要使用:类名.this访问
public class Outer { private int num = 10; public class Inner{ private int num = 20; public void show(){ int num = 30; System.out.println(num);//30 System.out.println(this.num);//20 //Outer.this 获取了外部类对象的地址值 System.out.println(Outer.this.num);//10 } } } public class Test { public static void main(String[] args) { Outer.Inner inner = new Outer().new Inner(); inner.show(); } }
2.静态内部类
2.1定义
静态内部类是一种特殊的内部类,它通过使用static
关键字来声明。与非静态内部类不同,静态内部类不需要依赖于外部类的实例即可创建。这意味着你可以直接通过外部类的名称来创建静态内部类的对象,而不需要先创建一个外部类的实例。
2.2注意事项:
- 静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建外部类的对象。
public class Outer2 { int a=10; static int b=20; static class Inner{ public void show(){ //创建外部类的对象来访问非静态的变量 Outer2 o = new Outer2(); System.out.println(o.a); //可以直接访问外部类中的静态变量 System.out.println(b); } } }
- 创建静态内部类对象的格式:外部类名.内部类名 对象名= new 外部类名.内部类名()
- 调用非静态方法的格式:先创建对象,用对象调用
- 调用静态方法的格式:外部类名.内部类名.方法名()
public class Outer { static class Inner{ public void show1() { System.out.println("非静态的方法被调用了"); } public static void show2() { System.out.println("静态的方法被调用了"); } } } public class Test { public static void main(String[] args) { // 调用非静态方法的格式:先创建对象,用对象调用 Outer.Inner i = new Outer.Inner(); i.show1(); //调用静态方法的格式:外部类名.内部类名.方法名() Outer.Inner.show2(); } }
3.局部内部类
3.1定义:
- 将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量
- 外界是无法使用局部内部类(例如:无法直接使用show方法里面的局部变量a),需要在方法内部创建对象并使用
- 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
public.static可以修饰成员变量但不可以修饰成员变量,也不可修饰局部内部类
3.2代码实现:
public class Outer {
int b=20;
public void show(){
int a=10;
//定义一个局部内部类
class Inner{
String name;
int age;
public void method1(){
//该类可以直接访问外部类的成员,也可以访问方法内的局部变量
System.out.println(a);
System.out.println(b);
System.out.println("局部类中的方法1");
}
public static void method2(){
System.out.println("局部类中的静态方法2");
}
}
//外界是无法使用局部内部类,需要在方法内部创建对象并使用
Inner inner = new Inner();
System.out.println(inner.name);
System.out.println(inner.age);
inner.method1();
Inner.method2();
}
}
public class Test {
public static void main(String[] args) {
Outer o = new Outer();
o.show();
}
}
4.匿名内部类
4.1定义:
匿名内部类是一种特殊的内部类。它没有显式的名字,也就是说,当你创建一个匿名内部类的对象时,实际上是同时定义了一个类并且创建了它的实例。这种类型的类主要用于简化代码,尤其是在使用单次使用的子类或实现简单接口时,可以避免定义单独的类。
4.2匿名内部类的用途:
- 简化代码:当只需要一次性的对象,并且这个对象不需要一个明确的名字时,使用匿名内部类可以减少代码量。
- 事件监听器:在GUI编程中,经常用来创建事件监听器,如按钮点击监听等。
- Lambda表达式的前身:在Java 8引入Lambda表达式之前,匿名内部类是处理函数式接口的主要方式。虽然Lambda表达式更加简洁,但在一些复杂的场景下,还是可能需要用到匿名内部类。
4.3定义格式:
//定义一个接口 public interface A { public void method(); } public class Test { public static void main(String[] args) { //匿名内部类,实现接口A,重写接口里面的方法 A a = new A(){ @Override public void method() { System.out.println("我是重写接口的方法"); } }; a.method(); } }