内部类:
就是将一个类嵌套在一个类的内部,就把内部类当作类中一个普通的属性来看待。
内部类的设计也是一种封装的思想,体现了保护性和易用性。
public class Outter {
private String msg = "Outter中的msg属性";
private static int age = 0;
public void fun() {
System.out.println("--------Outter的fun方法--------");
//可以访问内部类的私有属性,但是需要通过内部类对象
Inner inner = new Inner();
inner.fun();
System.out.println(inner.innerMsg);
}
//---------------------------------------------------
//成员内部类
class Inner {
private String innerMsg = "inner中的msg属性";
public void fun() {
System.out.println("--------Inner的fun方法--------");
//访问内部类的innerMsg属性
System.out.println(innerMsg);
//访问外部类的私有属性
System.out.println(msg);
}
}
//---------------------------------------------------
public static void main(String[] args) {
Outter outter = new Outter();
outter.fun();
}
}
内部类存在的原因
1.内部类和外部类可以方便的访问彼此的私有域(属性和方法)
2.内部类可以对外部类的外部完全隐藏(把内部类就当做外部类的属性来看待)
3.内部类可以变相实现多继承(实际开发中用的不多,了解即可)。
内部类的分类
~成员内部类
~静态内部类
~方法内部类
~匿名内部类
1.成员内部类:
在外部类的内部不使用静态关键字定义的内部类就是成员内部类,类比成员属性和成员方法。成员内部类需要依赖外部类对象,现有外部类,才有内部类对象。
成员内部类产生对象的两种方式:
a.在外部类的内部产生成员内部类对象∶在 Outter 的内部产生 Inner 对象就和普通类没啥区别
内部类名称 内部类引用 = new 内部类();
b.若内部类对外部可见(不是 private 修饰的内部类)在外部类的外部创建内部类对象
外部类名称.内部类名称 内部类引用 = new 外部类().new内部类();
Outter.Inner inner = new Outter().new Inner();
public class Test {
public static void main(String[] args) {
Outter.Inner inner = new Outter().new Inner();
inner.fun();
//需要注意的是Inner 这个内部类对 Test 是可见的
}
}
注意://需要注意的是Inner 这个内部类对 Test 是可见的。
c.当内部类使用 private 关键字修饰时,就是私有内部类,对外不完全不可见
问题:
成员内部类能否访问外部类中的静态域?(a)能否在当前内部类中自己定义静态域?(b)
a.可以。成员内部类已经拥有了外部类的对象都有对象了,当然就能访问静态属性。
b.不可以。假设可以,成员内部类静态属性,不需要产生对象就能调用的。但是成员内部类必须要依赖外部类对象才能产生。所以矛盾。
2.静态内部类∶
使用static关键字定义在另一个类的内部的类,可以看作是静态方法或属性。
和成员内部类最大的区别 ,是静态内部类不需要外部类的对象,和外部类是一个相对独立的关系,只是套在外部类的内部定义而已。
问题:
a.静态内部类中能否访问外部类的成员属性?
不能。静态内部类只能访问外部类的静态域,没有外部类对象,无法直接访问外部类的成员域
但是可以通过创建外部类对象访问。
public class StaticOutter {
private static String staticMsg = "外部类的静态私有属性";
private String msg = "外部类成员私有属性";
//静态内部类
static class Inner {
public void fun() {
StaticOutter outter = new StaticOutter();
System.out.println(outter.msg);
}
}
}
b.静态内部类中能否访问外部类的静态属性?
能。静态域都不需要对象。
public class StaticOutter {
private static String staticMsg = "外部类的静态私有属性";
private String msg = "外部类成员私有属性";
//静态内部类
static class Inner {
public void fun() {
System.out.println(staticMsg);
}
}
}
3.方法内部类
用的很少。
首先创建一个方法内部类
public class MethodClass {
public static void main(String[] args) {
fun(20);
}
public static void fun(int num) {
int i = 10;
//方法内部类,直接定义在方法内部的类。
class Inner {
void test() {
System.out.println(i);
System.out.println(num);
}
}
Inner inner = new Inner();
inner.test();
}
}
1.不能使用任何权限修饰符(这个类出了方法就没了)
2.对外部完全隐藏(外部类的外部)
3.内部类要使用方法的形参或者局部变量,该变量必须为隐式的final声明
方法内部类要使用外部方法中的形参或者局部变量,只有读取权,无法修改
4.若方法内部类中读取了方法中的局部变量(形参或者局部变量),这个局部变量就无法修改(不仅在内部类中没法改,在方法中也不能改)
5.在方法内部类中无法定义static域
4.匿名内部类
定义在方法中,可以是实参也可以是形参,其中实参使用的最多。
没有任何权限修饰符,甚至连类名称都没有的内部类。
其中的 public 是为了符合重写的语法,实际代码执行时没有任何意义。
public class NoNameClass {
public static void main(String[] args) {
fun(new IMessage() {
@Override
public void getMsg(String msg) {
}
});
}
public static void fun(IMessage message) {
message.getMsg("测试匿名内部类");
}
}
interface IMessage {
void getMsg(String msg);
}
接口无法直接实例化对象的,因此我们此处其实new的是IlMessage接口的子类只不过这个子类只在fun方法中使用一次