您的位置:

Java内部类的作用

Java内部类是一种定义在另一个类中的类。它的作用很广泛,可以应用于多个场景。本文从多个方面来阐述Java内部类的作用。

一、封装实现细节

内部类与外部类之间存在着直接的联系,内部类可以访问外部类的所有成员变量和成员方法,包括私有的成员。因此,内部类可以用来封装实现细节。对于外部类的用户来说,内部类是不可见的,只能调用外部类提供的公共方法。这样就可以避免外部类的实现细节暴露出来。

public class Outer {
    private int outerNum;
    
    public void display() {
        Inner inner = new Inner();
        inner.showOuterNum();
    }
    
    private class Inner {
        public void showOuterNum() {
            System.out.println("Outer Num: " + outerNum);
        }
    }
}

上面的代码中,内部类Inner可以访问外部类Outer的私有变量outerNum,同时外部类的用户也只能调用display方法,而不能直接访问outerNum。

二、实现接口和抽象类

内部类可以实现接口和抽象类,当内部类实现接口或抽象类时,可以隐藏实现细节,对外只提供接口或抽象类定义的方法,更好的实现了封装。同时,内部类可以访问外部类的成员变量和成员方法,方便实现接口或抽象类的方法。

public interface Shape {
    int getCircumference();
    int getArea();
}

public class Triangle {
    private int a;
    private int b;
    private int c;
    
    public Triangle(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    
    public Shape getShape() {
        return new TriangleShape();
    }
    
    private class TriangleShape implements Shape {
        public int getCircumference() {
            return a + b + c;
        }
        
        public int getArea() {
            int p = (a + b + c) / 2;
            return (int) Math.sqrt(p * (p - a) * (p - b) * (p - c));
        }
    }
}

上面的代码中,Triangle实现了一个Shape接口,通过getShape方法返回内部类TriangleShape的实例,TriangleShape实现了Shape接口的方法并可以访问Triangle的成员变量a、b、c,将Triangle的实现细节完全封装。

三、简化代码逻辑

内部类可以方便地访问外部类的成员变量和成员方法,在某些情况下可以简化代码逻辑。例如在事件处理中使用内部类可以避免代码逻辑复杂。下面是一个具体的例子。

public class Button {
    private OnClickListener mOnClickListener;
    
    public interface OnClickListener {
        void onClick();
    }
    
    public void setOnClickListener(OnClickListener onClickListener) {
        mOnClickListener = onClickListener;
    }
    
    public void click() {
        if (mOnClickListener != null) {
            mOnClickListener.onClick();
        }
    }
}

public class Test {
    public static void main(String[] args) {
        Button button = new Button();
        button.setOnClickListener(new Button.OnClickListener() {
            public void onClick() {
                System.out.println("Button clicked");
            }
        });
        button.click();
    }
}

上面的代码中,Button定义了一个内部接口OnClickListener和一个setOnClickLIstener方法,Test类使用匿名内部类实现了OnClickListener接口,并将实例设置到Button中。当click方法被调用时,会调用OnClickListener的onClick方法,输出“Button clicked”。

四、实现多次继承

内部类可以实现多次继承,即一个类可以继承一个类或实现一个接口,同时又可以在内部类中继承或实现另一个类或接口。这样可以避免类的继承层次过深,提高代码的可读性和可维护性。下面是一个例子。

public interface Flyable {
    void fly();
}

public class Bird {
    public void sing() {
        System.out.println("Bird is singing");
    }
}

public class Sparrow {
    private Bird mBird = new Bird();
    
    public void sing() {
        mBird.sing();
    }
    public void fly() {
        System.out.println("Sparrow is flying");
    }
}

上面的代码中,Sparrow类包含了一个Bird实例,并将其包装了一下来实现sing方法。但是这种方式违背了单一责任原则,同时也没法实现Flyable接口。下面我们使用内部类来实现多次继承。

public class Sparrow {
    public void sing() {
        System.out.println("Sparrow is singing");
    }
    
    public Flyable getFlyable() {
        return new FlyableImpl();
    }
    
    private class FlyableImpl implements Flyable {
        public void fly() {
            System.out.println("Sparrow is flying");
        }
    }
}

上面的代码中,Sparrow类实现了Bird类的sing方法并实现了Flyable接口,通过getFlyable方法返回内部类FlyableImpl的实例,FlyableImpl实现了Flyable接口中的fly方法。Sparrow类的sing和fly方法都是通过内部类的实现来实现的,更加清晰和简洁。

总结

Java内部类的作用很广泛,可以用来封装实现细节、实现接口和抽象类、简化代码逻辑和实现多次继承等。在实际开发中,要根据场景选择不同的内部类实现方式,避免过度依赖内部类带来的问题。