内部类的简单使用
1.内部类的基本概念
内部类:就是在一个类的内部进行其他类结构的嵌套操作。
例:内部类的简单定义:
class Outter{
private String msg = "Outter中的字符串";
//定义一个内部类
//-------------------------------------------
class Inner{
private String inMsg = "Inner中的字符串";
//定义一个普通方法
public void fun(){
//调用msg属性
System.out.println(msg);
}
}
//-------------------------------------------
//在外部类中定义一个方法,产生内部类对象并且调用fun()方法
public void test(){
//内部类对象
Inner in = new Inner();
in.fun();
}
}
public class Test2{
public static void main(String[] args){
//外部类对象
Outter out = new Outter();
out.test();
}
}
通过以上代码发现内部类可以方便的操作外部类的私有访问。
但是,引入内部类后,程序的内部看似有些混乱,如果不使用内部类,将其拆分后实现同样的功能
class Outter{
private String msg = "Outter中的字符串";
//通过此方法才能取得msg属性
public String getMsg(){
return this.msg;
}
public void test(){
//3.此时的this就是在main方法中调用test的对象
Inner in = new Inner(this);
//6.调用该方法
in.fun();
}
}
class Inner{
private Outter out;
public Inner(Outter out){ //4.Inner.out = main.out
//5.引用传递
this.out = out;
}
public void fun(){
//7.执行此方法
System.out.println(out.getMsg());
}
}
public class Test2{
public static void main(String[] args){
//1.实例化Outter类对象
Outter out = new Outter();
//2.调用Outter类方法
out.test();
}
}
结果发现,拆分后的代码更复杂。
2.内部类存在的优缺点
通过以上代码结构,可以看出使用内部类有以下优点:
- 内部类与外部类可以方便的访问彼此的私有域(包含私有方法、私有属性)
- 内部类是另外一种封装(保护性),对外部的其他类隐藏(例如:心脏包在人身体内部)
- 内部类可以实现Java单继承局限
例:使用内部类实现多继承
class A{
private String msg = "张三";
public String getMsg() {
return msg;
}
}
class B{
private int age = 18;
public int getAge() {
return age;
}
}
class C{
private class InnerA extends A{
public String name(){
return super.getMsg();
}
}
private class InnerB extends B{
public int age(){
return super.getAge();
}
}
public String name(){
return new InnerA().name();
}
public int age(){
return new InnerB().age();
}
}
public class Test2{
public static void main(String[] args) {
C c = new C();
System.out.println(c.name());
System.out.println(c.age());
}
}
缺点:
- 结构太复杂
3.内部类与外部类的关系
- 对于非静态内部类,内部类的创建需要依赖外部类对象,在没有外部类实例之前无法创建非静态内部类
- 内部类是一个相互独立的个体,与外部类没有is-a关系(继承关系)
- 内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类元素,需要通过内部类的引用间接访问
例:内部类直接访问外部类元素
class Outter{
private String msg;
private int age;
class Inner{
public void display(){
//实际为Outter.this.msg,但可以直接使用
msg = "张三";
age = 18;
System.out.println(msg);
System.out.println(age);
}
}
public void fun(){
Inner in = new Inner();
in.display();
}
}
public class Test2{
public static void main(String[] args) {
Outter out = new Outter();
out.fun();
}
}
例:外部类可以通过内部类引用间接访问内部类元素
class Outter{
class Inner{
private String msg = "Inner中的字符串";
public void display(){
System.out.println(msg);
}
}
public void fun(){
//通过内部类引用来访问
Inner in = new Inner();
in.display();
}
}
public class Test2{
public static void main(String[] args) {
Outter out = new Outter();
out.fun();
}
}
4.创建内部类语法
4.1在外部类外部创建内部类语法
//创建非静态内部类
外部类.内部类 内部类引用 = new 外部类().new 内部类();
Outter.Inner in = new Outter().new Inner();
//创建静态内部类
外部类.内部类 内部类引用 = new 外部类.内部类();
Outter.Inner in = new Outter.Inner();
4.2在外部类内部创建内部类语法
在外部类内部创建内部类,就像普通对象一样直接创建
Inner in = new Inner();
5.内部类的分类
在Java中内部类的分类主要分为成员内部类、静态内部类、方法内部类、匿名内部类。
5.1成员内部类(类比成员方法)
- 成员内部类不能存在任何static变量或方法,但是可以访问外部类的静态域
- 成员内部类是依附外部类的,所以只有先创建外部类才能创建内部类
5.2静态内部类(类比静态方法)
- 静态内部类的创建不需要依赖外部类,可以直接创建
- 静态内部类不可以使用任何外部类的非static域 (包含属性与方法),但可以存在自己的成员变量。
例:使用static创建静态内部类
class Outter{
private static String msg = "hello world";
private int age = 18;
static class Inner{
public void display(){
//访问外部类的静态域
System.out.println(msg);
}
}
public void fun(){
Inner in = new Inner();
in.display();
}
}
public class Test2{
public static void main(String[] args) {
Outter out = new Outter();
out.fun();
}
}
将内部类中的方法进行修改:
static class Inner{
public void display(){
//访问外部类的非静态属性
System.out.println(age);
}
}
5.3方法内部类(局部内部类)
- 方法内部类不允许访问权限限制符 (public private protected 均不允许)
- 方法内部类对外部完全隐藏,除了创建这个类的方法可以使用外,其他地方均不能访问
- 方法内部类如果要想使用形参,该形参必须使用final声明(JDK8将形参变为final声明)
class Outter{
private int num = 5;
public void display(int temp){ //形参为final声明
//方法内部类,不能用权限声明
class Inner{
public void fun(){
System.out.println(num);
System.out.println(temp);
}
}
new Inner().fun();
}
}
public class Test2{
public static void main(String[] args){
Outter out = new Outter();
out.display(20);
}
}
5.4匿名内部类(lamdma表达式前身)
匿名内部类就是一个没有名字的内部类,因此特点与方法内部类完全一样,除此之外还有两个自己的特点:
- 匿名内部类必须继承一个抽象类或者实现一个接口
- 匿名内部类没有自己的构造方法,因为没有类名
例:使用匿名内部类
interface IInterface{
void test();
}
class Outter{
private int num;
public void display(){
//匿名内部类,实现了IInterface接口
new IInterface(){
@Override
public void test(){
System.out.println("匿名内部类");
}
}.test();
}
}
public class Test2{
public static void main(String[] args){
Outter out = new Outter();
out.display();
}
}