成员内部类
1、内部类可以访问外部类所有的属性和方法,包括private成员。可以用private、protected、public修饰
1 @Data 2 @ToString 3 public class Outer { 4 private double radius=0; 5 private static String name="Circle"; 6 public Outer(double radius){ 7 this.radius=radius; 8 } 9 private void outerMethod(){ 10 System.out.println("outerMethod"); 11 } 12 //内部类 13 class Inner{ 14 public Inner(){ 15 16 } 17 public void innerMethod(){ 18 System.out.println("innerMethod"); 19 //访问外部类的私有属性 20 System.out.println("radius:"+radius); 21 //访问外部类的静态属性 22 System.out.println("name:"+name); 23 //访问外部类的私有方法 24 outerMethod(); 25 } 26 } 27 }
内部类的创建需要一个外部类对象,可以通过如下的方法创建
1 public class MainApp { 2 public static void main(String[]args){ 3 Outer outer=new Outer(10); 4 //创建成员内部类的方法 5 Outer.Inner inner=outer.new Inner(); 6 inner.innerMethod(); 7 } 8 }
运行结果
2、如果外部类访问内部类的属性和方法需要先创建一个内部类对象,然后通过这个内部类对象来访问。
1 public class Outer { 2 private double radius=0; 3 private static String name="Outer"; 4 private Inner inner; 5 public Outer(double radius){ 6 this.radius=radius; 7 } 8 public void getInnerProperty(){ 9 System.out.println("getInnerProperty:"+getInnerInstance().innerName); 10 } 11 Inner getInnerInstance(){ 12 if (inner==null){ 13 return new Inner(); 14 } 15 return inner; 16 } 17 //内部类 18 class Inner{ 19 private String innerName="Inner"; 20 public Inner(){ 21 22 } 23 } 24 }
1 public class MainApp { 2 public static void main(String[]args){ 3 Outer outer=new Outer(10); 4 //创建成员内部类的方法 5 Outer.Inner inner=outer.new Inner(); 6 //外部类通过内部类实例访问内部类的属性 7 outer.getInnerProperty(); 8 } 9 }
运行结果:
3、如果外部类和内部类有重名的属性和方法
当外部类和成员来拥有相同的属性和方法时,会发生隐藏现象,即默认情况下访问的时成员内部类的成员。
外部类和内部类拥有同名的属性:"shape"和同名方法“hello”
1 public class Outer { 2 private double radius=0; 3 private String shape="Circle"; 4 public Outer(double radius){ 5 this.radius=radius; 6 } 7 8 private void hello(){ 9 System.out.println("Out say hello"); 10 } 11 //内部类 12 class Inner{ 13 private String shape="Rect"; 14 public Inner(){ 15 16 } 17 private void hello(){ 18 System.out.println("Inner say hello"); 19 } 20 public void visitTest(){ 21 hello(); 22 System.out.println("shape:"+shape); 23 } 24 } 25 }
1 public class MainApp { 2 public static void main(String[]args){ 3 Outer outer=new Outer(10); 4 //创建成员内部类的方法 5 Outer.Inner inner=outer.new Inner(); 6 inner.visitTest(); 7 } 8 }
执行结果:
如果要访问外部类同名的成员,要按照下面的方式访问
外部类.this.成员变量
外部类.this.成员方法
1 @Data 2 @ToString 3 public class Outer { 4 private double radius=0; 5 private String shape="Circle"; 6 public Outer(double radius){ 7 this.radius=radius; 8 } 9 private void hello(){ 10 System.out.println("Out say hello"); 11 } 12 //内部类 13 class Inner{ 14 private String shape="Rect"; 15 public Inner(){ 16 17 } 18 private void hello(){ 19 System.out.println("Inner say hello"); 20 } 21 public void visitTestV2(){ 22 Outer.this.hello(); 23 System.out.println("shape:"+Outer.this.getShape()); 24 } 25 } 26 }
1 public class MainApp { 2 public static void main(String[]args){ 3 Outer outer=new Outer(10); 4 //创建成员内部类的方法 5 Outer.Inner inner=outer.new Inner(); 6 inner.visitTestV2(); 7 } 8 }
Out say helloshape:Circle
局部内部类
局部内部类是定义在一个方法或者一个作用域内,它的访问权限仅在该方法内或作用域内。不可以用private、protected、public修饰。
1 package com.innerClass.part; 2 3 public class People { 4 public People(){ 5 } 6 }
1 public class Man { 2 public Man() { 3 4 } 5 6 public People getWoman() { 7 class Women extends People { 8 public int age = 10; 9 } 10 Women women=new Women(); 11 System.out.println("age:"+women.age); 12 return new Women(); 13 } 14 }
1 public class MainApp { 2 public static void main(String[]args){ 3 Man man=new Man(); 4 People people=man.getWoman(); 5 } 6 }
执行结果:
age:10
-
匿名内部类在编译的时候由系统自动起名为Outter$1.class。
-
一般来说,匿名内部类用于继承其他类或是实 现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
方法一: 接口名 实例名 = new 接口名(){ 实现接口中的所有抽象方法 };(分号不能掉) 实例名.方法名(); …
方法二: new 接口名(){ 实现接口中的所有抽象方法 }.方法名();(从后面开始直接调用方法)
下面写一个例子:
1 package com.innerClass.anonymous; 2 3 import java.math.BigDecimal; 4 5 public interface Operation { 6 BigDecimal compute(BigDecimal num1,BigDecimal num2); 7 }
1 public class InnerClass { 2 /** 3 * 加法 4 * @param a 5 * @param b 6 * @return 7 */ 8 public static BigDecimal add(BigDecimal a ,BigDecimal b){ 9 Operation operation=new Operation() { 10 @Override 11 public BigDecimal compute(BigDecimal num1, BigDecimal num2) { 12 return num1.add(num2); 13 } 14 }; 15 BigDecimal sum=operation.compute(a,b); 16 return sum; 17 } 18 19 /** 20 * 减法 21 * @param a 22 * @param b 23 * @return 24 */ 25 public static BigDecimal substract(BigDecimal a,BigDecimal b){ 26 return new Operation(){ 27 @Override 28 public BigDecimal compute(BigDecimal num1, BigDecimal num2) { 29 return num1.subtract(num2); 30 } 31 }.compute(a,b); 32 } 33 }
1 public class MainApp { 2 public static void main(String [] args){ 3 BigDecimal a=BigDecimal.valueOf(100); 4 BigDecimal b=BigDecimal.valueOf(50); 5 System.out.println(InnerClass.add(a,b)); 6 System.out.println( InnerClass.substract(a,b)); 7 } 8 }
执行结果:
150
50
静态内部类
静态内部类也是定义在另一个类里面的类,只是在类前面加了一个static,并且它不能使用外部类的非static成员或者方法。
1 public class Outer { 2 private String name="Outer"; 3 private static String shape="Circle"; 4 public Outer(){ 5 6 } 7 static class Inner{//在此类中不能访问name 8 public Inner(){ 9 System.out.println("shape:"+shape); 10 } 11 } 12 }
1 public class MainApp { 2 public static void main(String [] args){ 3 Outer.Inner inner=new Outer.Inner(); 4 } 5 }
执行结果: