Java 内部类

Java 内部类

所谓的内部类(Inner Class),顾名思义,就是将一个类定义在另外一个类的内部。一个类内部的类被称之为内部类。this

内部类基本语法

// Outer 为外部类,Inner 为内部类
public class Outer{
	class Inner{
		// ...
	}
}

内部类的主要特色:

  • 内部类能够很好的实现隐藏,可使用 protectedprivate 修饰符
  • 内部类能够直接访问外部类的全部成员,包括私有成员
  • 外部类不能直接访问内部类的成员,必须首先创建内部类的对象才可访问
  • 内部类能够解决一些问题,好比间接地区实现多继承。能够避免修改接口而实现同一个类中两种同名方法的调用

内部类间接实现多继承
示例:code

public class MultiExtends{
	public static void main(String[] args){
		C c = new C();
		// 访问 A 类中的 showA() 方法
		c.getInstanceA1();
		// 访问 B 类中的 showB() 方法
		c.getInstanceB1();
	}
}
class A{
	public void showA(){
		System.out.println("A");
	}
}
class B{
	public void showB(){
		System.out.println("B");
	}
}
// 至关于同时继承了 A 类和 B 类
class C{
	// 内部类 A1
	private class A1 extends A{
		public void showA(){
			// 继承 A 类的 showA()方法
			supper.showA();
		}
	}
	// 内部类 B1
	private class B1 extends B{
		public void showB(){
			// 继承 B 类的 showB()方法
			supper.showB();
		}
	}
	// 给外部提供访问内部私有类 A1 内的方法 的接口
	public void getInstanceA1(){
		 new A1().showA();
	}
	// 给外部提供访问内部私有类 B1 内的方法 的接口
	public void getInstanceB1(){
		 new B1().showB();
	}
}

内部类实现父类与接口中的同名方法
示例:对象

public class MutilExtendsImplement{
	public static void main(String[] args){
		Son son = new Son();
		// 访问抽象父类的 show() 方法
		son.show();
		// 访问接口中的 show() 方法
		son.showSonInner();
	}
}
// 抽象类
abstract class Parent{
	// 抽象类中的 show() 抽象方法
	public abstract void show();
}
// 接口
interface IShow{
	// 接口中的 show() 方法
	// public void show();
	public void show1();
}

// 这种作法是不容许的,由于 Parent 类和 IShow() 存在同名方法 show(), Son 类不知道该实现哪一个 show() 方法 ,除非 抽象父类或者接口任一个修改方法名
// Son 类继承 Parent 类并实现 IShow 接口
class Son extends Parent implements IShow{
	// 实现抽象父类
	public void show(){
		...
	}
	// 接口中的方法名改成 show1()
	public void show1(){
		...
	}
}

// 若抽象父类和接口都不修改方法名,能够由内部类来实现
// 抽象类
abstract class Parent{
	// 抽象类中的 show() 抽象方法
	public abstract void show();
}
// 接口
interface IShow{
	// 接口中的 show() 方法
	public void show();
}
class Son extends Parent{
	// 实现抽象父类的 show() 方法
	public void show(){
		System.out.println("抽象类中的 show() 方法");
	}
	// 定义一个内部类来实现 IShow 接口
	private class SonInner implements IShow{
		// 实现接口的 show() 方法
		public void show(){
			System.out.println("接口中的 show() 方法");
		}
	}
	// 提供给外部访问私有内部类 SonInner 方法的接口
	public void showSonInner(){
		new SonInner.show();
	}
}

内部类的分类

  • 成员内部类
  • 静态内部类
  • 匿名内部类
  • 局部内部类

成员内部类及应用

成员内部类特色:继承

  • 成员内部类属于外部类的实例成员,成员内部类能够有public、private、default、protected 权限修饰符,在成员内部类中访问外部类的成员方法和属性,要使用“外部类名.this.成员方法” 和“外部类名.this.成员属性”的形式。

注:若成员内部类与外部类有同名方法或同名属性,成员内部类在访问外部类的同名方法或属性时要使用“外部类名.this.(外部)成员方法(属性)”形式,若成员内部类访问的是与外部内非同名的方法或属性,直接使用“方法名”或“属性名”访问便可接口

  • 建立成员内部类的实例使用“外部类名.内部类名 实例名 = 外部类实例名.new 内部类构造方法(参数)”的形式
    成员内部类有如下限制
  • 成员内部类不能与外部类重名
  • 不能在成员内部类中定义 static 属性、方法和类(static final 形式的常量定义除外)。由于一个成员内部类实例比必然与一个外部类实例关联,static 成员彻底能够移到其外部类中去
  • 外部类不能直接访问成员内部类的方法和属性,能够在外部类中声明并建立成员内部类的实例,再经过成员内部类的实例来访问成员内部类的方法和属性

示例:作用域

public class MenberInnerClass{
	// 程序主方法
	public static void main(String[] args){
		Outer outer = new Outer();
		// 建立内部成员类实例
		Outer.Inner innre = outer.new Inner();
	}
}
// 外部类 Outer
class Outer{
	// 外部类属性
	private String name;
	private int number;
	// 外部类方法
	public void showOuter(){
		System.out.println(name);
		System.out.println(number);
		// 外部类不能直接访问内部类的成员方法和属性
		// System.out.println(number2);
		}
	// 内部类 Inner
	public class Inner{
	private String name;
	private int number2;
	// 在成员内部类中不能声明静态的成员,包括属性和方法
	// public static int number3 = 30;
	// 在成员内部类中能够声明静态的常量
	private static final int number3 = 30;
	public void showInner(){
		System.out.println(name);
		System.out.println(number2);
		// 内部类调用外部类成员
		System.out.println(Outer.this.name);
		// 内部类调用外部类方法
		Outer.this.showOuter();
		}
	}
}

静态内部类及应用

静态内部类特色get

  • 使用 static 修饰的成员内部类叫静态内部类
  • 静态内部类跟外部类没有任何关系,只是在生成类名和类定义时有影响。静态内部类能够看做是与外部类平级的类。使用方式与外部类平级的类彻底相同
  • 建立静态内部类的实例使用 外部类名.内部类名 实例名 = new 外部类名.内部类名(参数) 例如:Outer.Inner inner = new Outer.Inner();

静态内部类有如下限制io

  • 静态内部类名字不能与外部类重名
  • 静态内部类不能访问外部类中的非静态的属性和方法,外部类不能直接访问内部类中的非静态成员,可是能够经过在外部类中构造内部类的实例,而后用实例来调用静态内部类中的非静态成员,外部类能够直接访问静态内部类的静态成员,以 静态内部类.成员 的形式,例如:StaticInner.name

匿名内部类及应用

匿名内部类特色class

  • 匿名内部类是 没有名称 的内部类,没办法引用它们,必须在建立时做为 new 语句的一部分来声明并建立它们的实例
  • 匿名内部类必须继承一个类(抽象的、非抽象的均可以)或者实现一个接口;若是父类(或者父接口)是抽象类,则匿名内部类必须实现其全部抽象方法
  • 匿名内部类中能够定义代码块,用于实例的初始化,可是不能定义静态代码块

匿名内部类语法变量

new interface/superclass() {//类体}

  • 这种形式的 new 语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口,并同时建立该匿名类的一个新实例

示例:

public class AnonymousInnerClass{
	public static void main(String[] args){
		Person person = new Person();
		// 利用匿名内部类实例化 Animail 的一个子类
		person.feed(new Animial(){
			// 实现抽象类中的抽象方法 eat()
			public void eat(){
				System.out.println("eating");
			}
		});
		// 利用匿名内部类实现接口 Animail
		persion.feed(new Animail(){
			public void move(){
				System.out.println("moving");
			}
		});
	}
}
class Person{
	// feed 方法传入 Animial 对象执行 eat() 方法
	public void feed(Animail animail){
		animail.eat();
	}
}
// 抽象父类 Animail
abstract class Animail{
	// 抽象方法 eat()
	public abstract void eat();
}
// 接口 Animail
interface Animail{
	public void move();
}

局部内部类及应用

局部内部类特色

  • 定义在代码块、方法体内的类叫局部内部类
  • 局部内部类访问外部类的属性和方法使用 “外部类名.this.属性名” 和 “外部类名.this.方法名(参数)” 的形式
  • 对外部世界彻底隐藏,只能在其做用域内生成对象

局部内部类有如下限制

  • 局部内部类不能加访问修饰符,由于它们并非类成员
  • 成员内部类不能与外部类重名
  • 局部内部类访问做用域内的局部变量,该局部变量须要使用 fianl 访问修饰符

示例:

public class LocalInnerClass{
	public static void main(String[] args){
		Outer outer = new Outer();
		// 经过调用 Outer 的 showOuter() 方法来调用局部内部类 Inner
		outer.showOuter();
	}
}
class Outer{
	private String name = "tom";
	private int num1 = 10;
	public void showOuter(){
		// 局部变量
		int num2 = 20;
		// 局部内部类 Inner,定义在 showOuter() 方法中
		class Inner{
			private String name = "jack";
			private int num3 = 30;
			public void showInner(){
				System.out.println(name);
				System.out.println(num3);
			}
		}
		// 构造局部内部类的实例,只能在当前这个方法的做用域内构造
		Inner inner = new Inner();
		inner.showInner();
	}
}
相关文章
相关标签/搜索