内部类:把一个类放在另一个类中定义,那么这么定义在内部的类就叫做内部类。
内部类的作用:
1.内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。
2.内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问,但外部类不能访问内部类的实现细节,例如内部类的成员变量。
3.匿名内部类适合用于创建那些仅需要一次使用的类。
非静态内部类:
下面是在内部类中访问外部类的私有变量及调用内部类的Demo:
public class Dog {
private String name;
public Dog() {
}
public Dog(String name) {
this.name = name;
}
private class DogHead {
private String furColor;
public DogHead() {
}
public DogHead(String furColor) {
this.furColor = furColor;
}
public void print() {
/**
* 访问外部类的私有变量
* @author Guo
*/
System.out.println("Name:" + name + " FurColor:" + furColor);
}
}
public void test() {
DogHead dogHead = new DogHead("yellow");
dogHead.print();
}
public static void main(String[] args) {
Dog dog = new Dog("GG");
dog.test();
}
}
需要提醒的是:
非静态内部类不能有静态方法、静态Field、静态初始化块
静态内部类:
用static修饰的内部类称为静态内部类
下面是一个Demo:
public class OutClass {
private String word1 = "word1";
private static String word2 = "word2";
static class InClass {
public void access() {
/**
* 不能直接访问外部类的私有非静态变量,要访问需要生成实例再来访问
*/
//System.out.println(word1);
/**
* 可以直接访问外部类的静态变量
*/
System.out.println(word2);
}
}
}
使用内部类:
非静态内部类的访问:
class Out {
class In {
public In(String message) {
System.out.println(message);
}
}
}
public class CreateInnerClassInstance {
public static void main(String[] args) {
/**
* 创建外部类的实例,非静态内部类实例将寄存在该实例中
* 通过外部类实例和new来调用内部类构造器创建非静态内部类实例
*/
Out.In in = new Out().new In("Hello World");
}
}
静态内部类的访问:
class StaticOut {
static class StaticIn {
public StaticIn(String message) {
System.out.println(message);
}
}
}
public class CreateStaticInnerClassInstance {
public static void main(String[] args) {
/**
* 通过new来调用内部类构造器创建静态内部类的实例
*/
StaticOut.StaticIn in = new StaticOut.StaticIn("Hello World");
}
}
局部内部类:
如果把一个内部类放在方法里定义,这个内部类就是一个局部内部类
public class LocalInnerClass {
public static void main(String[] args) {
class In {
private String name = "In";
public String getName() {
return this.name;
}
}
In in = new In();
System.out.println(in.getName());
}
}
匿名内部类:
1.匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象
2.匿名内部类不能定义构造器,因为匿名内部类没有类名,所以无法定义构造器,但是匿名内部类可以定义实例初始化块
public interface Animal {
public String getName();
public String getAge();
}
public class Test {
public void use(Animal animal) {
System.out.println("Name:" + animal.getName() + " Age:" + animal.getAge());
}
public static void main(String[] args) {
Test test = new Test();
test.use(new Animal() {
@Override
public String getName() {
return "Xxx";
}
@Override
public String getAge() {
return "21";
}
});
}
}