java学习-内部类
内部类
- 一个类定义在另外一个类的内部,这个类称为内部类; 可以将内部类定义在方法中,也可以将内部类定义在成员位置, 根据定义位置不同, 功能和使用方式不同
class Car{ // 外部类
class 发动机{ // 内部类
}
}
2.根据内部类定义位置不同 :
1) 成员内部类
普通成员内部类
私有成员内部类
静态成员内部类
2) 局部内部类
有名普通局部内部类
匿名内部类(掌握)
1. 普通成员内部类
- 定义位置 : 定义在成员位置的内部类
- 语法结构:
class Body{
class Heart{ // 理解成普通成员变量
// 成员变量, 方法
}
}
3.普通成员内部类使用:
1) 内部类可以直接使用外部类中的成员
2) 在外部类中, 要使用普通成员内部类, 先创建出一个内部类对象,使用内部类对象.调用内部类中的成员变量和方法
3) 除了外部类之外的其他类型中,如果想要直接使用内部类, 使用公式:
外部类名.内部类名 内部类名字 = new 外部类对象().new 内部类对象();
代码
1 public class Body1 {// 外部类 2 // blood表示血压 3 int blood = 120; 4 // 普通成员内部类 5 class Heart{ 6 // 心跳变量 7 int boom = 80; 8 9 // 定义出一个心脏跳动的方法 10 public void jump() { 11 // 普通成员内部类可以直接使用外部类中的成员 12 System.out.println("血压"+blood+",每分钟心跳为:"+boom); 13 } 14 } 15 16 // 定义出方法 : 使用Heart内部类 17 public void useHeart() { 18 Heart h = new Heart(); 19 System.out.println(h.boom); 20 h.jump(); 21 } 22 }
public class TestInnerClass { public static void main(String[] args) { // 1. 测试普通成员内部类 // 1) 创建出一个外部类对象 Body1 b1 = new Body1(); b1.useHeart(); // 2)除了外部类之外的其他类型中,如果想要直接使用内部类, 使用公式: // 外部类名.内部类名 内部类名字 = new 外部类对象().new 内部类对象(); Body1.Heart heart = new Body1().new Heart(); System.out.println(heart.boom); heart.jump(); } }
2. 私有成员内部类
- 定义位置 : 定义在成员位置的内部类, 内部类使用关键字private修饰
- 语法结构:
class Body2{
private class Shen{
// 成员变量, 方法
}
}
3.私有成员内部类使用:
1) 私有成员内部类可以直接使用外部类中的成员
2) 私有成员内部类,只能在当前的外部类中使用, 除了外部类之外,其他类型无法直接使用私有成员内部类; 需要在外部类中,提供对外的访问私有成员内部类的方式
代码
public class Body2 { int drink = 10; // 定义出私有成员内部类 private class Shen{ int wc = 5; public void goToWc() { // 1)私有成员内部类可以直接使用外部类中的成员 System.out.println("一天喝了"+drink + "升水,去卫生间"+wc+"次,好好排毒~~"); } } // 在外部类中,提供对外的访私有成员内部类的方式 public void useShen() { Shen sh = new Shen(); System.out.println(sh.wc); sh.goToWc(); } }
public class TestInnerClass { public static void main(String[] args) { // 2. 测试私有成员内部类 Body2 b2 = new Body2(); b2.useShen(); } }
3. 静态成员内部类
- 定义位置 : 定义在成员位置的内部类, 内部类使用关键字static修饰
- 语法结构:
class Body3{
static class Gan{
// 成员变量,方法
}
}
3.静态成员内部类使用:
1) 静态成员内部类中可以直接使用外部类中的静态成员; 如果使用外部类中的非静态成员, 需要先创建出一个外部类对象, 才能使用
2) 静态成员内部类中 : 静态成员, 可以使用外部类名.内部类名.直接调用
3) 静态成员内部类中 : 非静态成员, 需要创建出内部类对象才能使用
外部类名.内部类名 静态内部类名字 = new 外部类名.内部类名()
代码
public class Body3 { String name = "张三"; static int drink = 10; // 静态成员内部类 static class Gan{ int day = 2; static int drinkNow = 1; public void jiu() { // 1. 创建出一个外部类Body3对象, 为了使用外部类中的非静态成员 Body3 b3 = new Body3(); System.out.println(b3.name + day + "天,喝了" + drink + "斤酒,喝多了,最好喝" + drinkNow + "斤比较合适"); } } }
public class TestInnerClass { public static void main(String[] args) { // 3. 静态成员内部类测试 // 静态成员内部类中 : 静态成员, 可以使用外部类名.内部类名.直接调用 System.out.println(Body3.Gan.drinkNow); // 创建出一个静态成员内部类对象 // 外部类名.内部类名 静态内部类名字 = new 外部类名.内部类名(); Body3.Gan b3 = new Body3.Gan(); System.out.println(b3.day); b3.jiu(); } }
4. 普通局部内部类
- 定义位置 : 定义在一个方法中的内部类
- 语法结构:
void breath(){
class Fei{
// 成员变量,方法
}
}
3.普通局部内部类的使用:
1) 在方法中定义出的局部变量, 外界无法直接获取到这个变量, 只能通过方法的运行间接使用局部变量; 同理, 局部内部类需要通过方法的运行, 间接访问到这个局部内部类
2) 定义好了局部内部类之后,在当前方法中,直接创建出一个局部内部类对象, 调用局部内部类中的属性和方法
public class Demo_局部内部类 { public static void main(String[] args) { breath(); Demo_局部内部类.breath(); } // 定义出一个方法功能 public static void breath() { int i = 10; // 定义出一个布局内部类 class Fei{ String color = "黑色"; public void smoke() { System.out.println("每天吸" + i + "根烟, 有一天你的肺有可能变成" + color); } } // 创建出一个局部内部类对象 Fei f = new Fei(); System.out.println(f.color); f.smoke(); } }
5.匿名内部类
- 匿名内部类 : 定义在方法中, 没有名字的内部类
- 匿名内部类作用:
可以作为一个类的子类或者是作为一个接口的实现类
3.匿名内部类语法结构:
new 父类或者父接口(){
// 大括号表示对于父类或者父接口的实现过程
父类或者父接口中的方法重写;
};
4.匿名内部类的使用:
1) 定义出一个匿名内部类之后, 只能使用一次, 使用方法:
new 父类或者父接口(){
}.调用一次数据内容;
2) 匿名内部类使用优化 :
将匿名内部类对象通过多态表达方式, 使用一个父类或者父接口完成表达式
父类或者父接口 变量名= new 父类或者父接口(){
};
变量名.可以任何的多次的调用匿名内部类实现和继承到的方法功能;
代码
public interface MyInter { public abstract void fun(); public abstract int getSum(int x, int y); }
public class Demo_匿名内部类 { public static void main(String[] args) { // 1. 创建出一个MyInter接口匿名内部类 new MyInter() { // 大括号表达式接口MyInter的实现类实现过程 @Override public void fun() { System.out.println("匿名内部类实现fun"); } @Override public int getSum(int x, int y) { return x + y; } }.fun(); // 2. 匿名内部类对象优化 // 使用多态, 利用父接口引用指向实现类对象 MyInter my = new MyInter() { // 大括号表达式接口MyInter的实现类实现过程 @Override public void fun() { System.out.println("匿名内部类实现fun"); } @Override public int getSum(int x, int y) { return x + y; } }; my.fun(); int result = my.getSum(4, 5); System.out.println(result); } }