内部类
什么是内部类
1、概念
在一个类的内部再定义一个完整的类。
2、特点
-
编译之后可生成独立的字节吗文件
package com.zhang.demo01; /** * @ClassName MemberInner * @Description TODO 测试内部类 * @Author Administrator * @Date 2021/2/1 1:05 * @Version 1.0 **/ public class MemberInner { public static void main(String[] args) { } class MI1{ } }
*ps:
如果你写的类里包含有内部类 ,那么在编译的时候会生成对应内部类的class文件(格式:主类$内部类.class),但是在IDEA的工程里是看不到的,只能在本地文件夹打开来看到.
-
内部类可直接访问外部类的私有成员,而不破坏封装
-
可为外类提供必要的内部功能组件
1.成员内部类
-
在类的内部定义,与实例变量、实例方法同级别的类。
-
外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。
-
当外部类、内部类存在重名属性时,会优先访问内部类属性
-
成员内部类不能定义静态成员,但可以包含静态常量
-
示例代码
package com.zhang.demo02;
/**
* @ClassName Outer
* @Description TODO 测试成员内部类
* @Author Administrator
* @Date 2021/2/1 14:37
* @Version 1.0
**/
//外部类
public class Outer {
//实例变量
private String name = "小张";
private int age = 20;
//内部类
class Inner {
private String address = "中国";
private String pehone = "110";
//Inner classes cannot have static declarations
// private static String city = "广州";
//方法
public void show(){
//打印外部类的属性,内部类属性和外部类的属性名字相同 使用Outer.this
System.out.println(Outer.this.name);
System.out.println(Outer.this.age);
//打印内部类的属性
System.out.println(address);
System.out.println(pehone);
}
}
}
package com.zhang.demo02;
import com.zhang.demo02.Outer.Inner;
import sun.applet.Main;
/**
* @ClassName TestOuter
* @Description TODO
* @Author Administrator
* @Date 2021/2/1 15:32
* @Version 1.0
**/
public class TestOuter {
public static void main(String[] args) {
// 1、创建外部类对象
Outer outer = new Outer();
// 2、创建内部类对象
Inner inner = outer.new Inner();
// 一步到位
// Inner inner =new Outer().new Inner();
inner.show();
}
}
2.静态内部类
-
不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。
-
只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
-
示例代码
package com.zhang.demo03; /** * @ClassName Outer * @Description TODO 测试静态内部类 * @Author Administrator * @Date 2021/2/1 15:50 * @Version 1.0 **/ //外部类 public class Outer { private String name="xiaozhang"; private int age = 18; //静态内部类:和外部类相同 static class Inner{ private String address="广州"; private String phone ="123"; //静态成员 private static int count= 1111; public void show(){ //调用外部类的属性 //1、先创建外部类对象 Outer outer = new Outer(); //2、调用外部类对象的属性 System.out.println(outer.name); System.out.println(outer.age); //调用静态内部类的属性和方法 System.out.println(this.address); System.out.println(this.phone); //调用静态内部类的静态成员 System.out.println(Inner.count); } } }
package com.zhang.demo03;
import com.sun.org.apache.bcel.internal.generic.NEW;
/**
* @ClassName TestOuter
* @Description TODO
* @Author Administrator
* @Date 2021/2/1 15:59
* @Version 1.0
**/
public class TestOuter {
public static void main(String[] args) {
// 直接创建静态内部类对象
Outer.Inner inner = new Outer.Inner();
// 调用方法
inner.show();
}
}
3.局部内部类
- 定义在外部类方法中,作用范围和创建对象范围仅限于当前放大。
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final
- 限制类的使用范围
- 示例代码1
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过这个外部类去实例化内部类~
Outer.Inner inner = outer.new Inner();
inner.getID();
}
package com.oop.demo11;
/**
* @ClassName Outer
* @Description TODO
* @Author Administrator
* @Date 2021/1/30 17:40
* @Version 1.0
**/
public class Outer {
private int id = 10;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性
public void getID(){
System.out.println(id);
}
}
public void method(){
//写在方法里边的局部内部类
class Inner{
public void in(){
}
}
}
}
- 示例代码2
package com.zhang.demo04;
/**
* @ClassName Outer
* @Description TODO 测试局部内部类 (写在方法里面的类)
* @Author Administrator
* @Date 2021/2/1 16:39
* @Version 1.0
**/
public class Outer {
private String name = "刘德华";
private int age =35;
public void show(){
//定义局部变量
String address= "广州";
//定义局部常量
String address1= "佛山";
//局部内部类:注意不能加任何访问修饰符
class Inner{
//局部内部类的属性
private String phone ="123123123";
private String email = "xiaozhang@qq.com";
//pivate final static int count = 2000;
public void show2(){
//访问外部类属性
System.out.println(Outer.this.name);
System.out.println(Outer.this.age);
//访问内部类的属性
System.out.println(this.phone);
System.out.println(email);
//访问局部变量,jdk1.7要求:变量必须是常量final.jdk1.8 默认自动添加fianl
System.out.println(address);
System.out.println(address1);
}
}
//创建局部内部类对象
Inner inner = new Inner();
inner.show2();
}
}
package com.zhang.demo04;
/**
* @ClassName TestOuter
* @Description TODO
* @Author Administrator
* @Date 2021/2/1 16:51
* @Version 1.0
**/
public class TestOuter {
public static void main(String[] args) {
Outer outer = new Outer();
outer.show();
}
}
4.匿名内部类
-
没有类名的局部内部类(一切特征都与局部内部类相同)
-
必须继承一个父类或者实现一个接口
-
定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
-
优点:减少代码量
-
缺点:可读性较差
-
示例代码
//接口
package com.zhang.demo05;
public interface Usb {
void service();
}
package com.zhang.demo05;
/**
* @ClassName Keyborad
* @Description TODO 实现接口 的类
* @Author Administrator
* @Date 2021/2/1 17:18
* @Version 1.0
**/
public class Keyboard implements Usb {
@Override
public void service() {
System.out.println("连接键盘,键盘开始工作了。。。");
}
}
package com.zhang.demo05;
import sun.applet.Main;
import javax.sound.midi.Soundbank;
/**
* @ClassName TestUsb
* @Description TODO
* @Author Administrator
* @Date 2021/2/1 17:25
* @Version 1.0
**/
public class TestUsb {
public static void main(String[] args) {
//创建接口类型的变量
Usb kb = new Keyboard();
kb.service();
// //局部内部类
// class Mouse implements Usb{
// @Override
// public void service() {
// System.out.println("连接鼠标,鼠标开始工作了...");
// }
// }
//
使用局部内部类创建对象
// Usb mouse =new Mouse();
// mouse.service();
// }
// 思考: 如果这个类只用一次,可不可以不优化代码,不写出来呢
//优化局部内部类————》匿名内部类
//相当于创建了一个局部内部类
Usb mouse1 = new Usb() {
@Override
public void service() {
System.out.println("再次连接鼠标");
}
};
mouse1.service();
}
}