面试后学习 -- Java内部类
2017-06-08 本文已影响85人
奔跑的笨鸟
面试问到的一个Java内部类的问题,今天总结下。如果我理解有误,请指正,谢谢。
一个简单的内部类:
package innerclazz;
public class OuterClazz {
class InnerClazz{//inner class
}
}
Java为什么用内部类
- 提供一种方法把只在一个地方用的类逻辑分组
- 增强封装(可以理解一种类似“多重继承”)
- 容易维护
为什么说内部类可以实现类似的多重继承,Java是不需要class多重继承的, 想要实现类似多重继承的效果可以用内部类,比如Class B 已经继承了Class C 就没有办法继承Class A, 但是把B设计成A的内部类,就可以访问A的内部变量和方法了,就像是也继承了A。
package innerclazz;
public class ClazzA {
private int age = 0;
public void printFromA(){
System.out.println("The age in ClazzA is "+age);
}
//ClazzB 可以直接调用ClazzA的方法和访问它的变量,
class ClazzB extends ClazzC{//inner class
public void print() {
age++;
printFromA();
}
}
public static void main(String[] args) {
ClazzB clazzB = new ClazzA().new ClazzB();
clazzB.print();
}
}
class ClazzC{
}
执行结果:
The age in ClazzA is 1
几种内部类
① 静态内部类
静态内部类不可以访问它外部类的非静态变量和方法,如果想访问外部类的变量和方法只能通过外部类的实例。
package innerclazz;
public class OuterClazz {
private int age = 0;
private static int intAge = 10;
public void printAge(){
System.out.println("The age in ClazzA is "+age);
}
//ClazzB 可以直接调用ClazzA的方法和访问它的变量,
static class ClazzB {//inner class
public void print() {
System.out.println("The int age in Out class is "+intAge);
OuterClazz outerClazz = new OuterClazz();
outerClazz.age++;
outerClazz.printAge();
}
}
public static void main(String[] args) {
ClazzB clazzB = new OuterClazz. ClazzB();
clazzB.print();
}
}
执行结果:
The int age in Out class is 10
The age in ClazzA is 1
② 非静态内部类
内部类可以直接访问外部类的方法和变量(包括静态的)。
package innerclazz;
public class OuterClazz {
private int age = 0;
private static int intAge = 10;
public void printAge(){
System.out.println("The age in ClazzA is "+age);
}
//ClazzB 可以直接调用ClazzA的方法和访问它的变量,
class ClazzB {//inner class
public void print() {
System.out.println("The int age in Out class is "+intAge);
age++;
printAge();
}
}
public static void main(String[] args) {
ClazzB clazzB = new OuterClazz(). new ClazzB();
clazzB.print();
}
}
执行结果和静态内部类相同。
③ 本地内部类
本地内部类声明在一个块中,函数本地类就是一个函数中声明一个类,作用域只在函数内,外部没办法创建实例
package innerclazz;
public class LocalClazz {
public static void testLocalClazz() {
int age =10;
class InnerClazz {
public void pringAge() {
//age++; //Error: Local variable age defined in an enclosing scope must be final or effectively final
System.out.println("this age is "+age);
}
}
InnerClazz innerClazz = new InnerClazz();
innerClazz.pringAge();
}
public static void main(String[] args) {
testLocalClazz();
}
}
④ 匿名类
没有名字的内部类就是匿名内部类,在声明的时候实例化,用来重写一个类的方法,或者实现一个接口
package innerclazz;
public class AnonymousInnerClazz {
private Animal animal = new Animal() {
@Override
public void eat() {
System.out.println("eat, eat, eat!");
}
};
public static void main(String[] args) {
new AnonymousInnerClazz().animal.eat();
}
}
interface Animal{
public void eat();
}
执行结果:
eat, eat, eat!
真的有点饿了,也累了,(~﹃~)~zZ