目录
内部类:将一个类定义在另一个类的内部,这种类称之为内部类。
内部类的设计也属于封装的一种,封装体现的保护性和易用性仍在内部类中体现。
根据内部类定义的位置以及关键字,一共分为以下四种内部类
成员内部类,静态内部类,方法内部类,匿名内部类
一、成员内部类
直接定义在一个类的内部,不加任何修饰符。
1、成员内部类的使用规则:
类比外部类的成员方法/属性
(1)成员内部类必须依赖外部类对象产生。先要产生外部类对象才能产生内部类对象。
关于成员内部类的实例化:
a.在外部类的内部进行实例化,就和普通类的产生一模一样。
public class MemberClass {
class Inner{
public void test(){
System.out.println("Inner类的Test方法");
}
}
public void fun(){
Inner inner = new Inner();
inner.test();
}
public static void main(String[] args) {
MemberClass memberClass = new MemberClass();
memberClass.fun();
}
}
b.在外部类的外部产生内部类的对象,前提是该内部类在外部是可见的。
外部类.内部类 内部类引用名称 = new 外部类().new 内部类();
public class Test {
public static void main(String[] args) {
MemberClass.Inner inner = new MemberClass().new Inner();
inner.test();
}
}
(2)成员内部类和它的外部类可以方便的互相访问彼此的私有域
内部类可以直接调用外部类的私有域,因为先要产生外部类对象才能产生外部类对象,而每个成员内部类的内部都隐藏了一个外部类对象,所以在内部类中直接调用外部类的this也是可以实现的。产生内部类对象,外部类对象会被编译器自己传入内部类中。
外部类通过内部类对象访问内部类的私有域。
public class MemberClass {
static private int a = 10;
private void he(){
System.out.println("外部类的私有方法he");
}
private class Inner{
private int b = 20;
private void testPrivate(){
System.out.println(a);
he();
System.out.println("内部类的私有成员方法testPrivate");
}
public void test(){
System.out.println("Inner类的Test方法");
}
}
public void fun(){
Inner inner = new Inner();
inner.test();
System.out.println(inner.b);
inner.testPrivate();
}
public static void main(String[] args) {
MemberClass memberClass = new MemberClass();
memberClass.fun();
}
}
在主方法中创建MemberClass类的对象,调用fun函数,fun函数中创建Inner类的对象调用test函数和Inner类的成员变量b,然后再test函数中调用MemberClass中的成员变量a和方法he。
(3)在成员内部类中不能定义任何静态域
可以访问外部类的静态域,但是不能在内部类中定义静态域。
(4)内部类可以是用private进行修饰封装,对外部完全隐藏。
(5)内部类和外部类不是继承关系,而是has a 关系,拥有/包含关系。和组合关系不一样,组合中定义不在外部类中,
二、静态内部类
直接定义在外部类之中,使用关键字static修饰的称为静态内部类。
静态内部类和普通类一样,只不过是定义在一个类的内部而已,不需要依赖外部类对象。
1、关于静态内部类的使用
(1)不需要依赖外部类对象,只是定义在一个外部类的内部而已。
a.在外部类的内部创建静态内部类对向,和普通内部类一样。
b.在外部类的外部创建静态内部类的对象,不需要依赖外部类对象,但是静态内部类必须得对外当前创建位置可见。
外部类.内部类 内部类引用名称 = new 外部类.内部类();
意味着没有产生外部类对象,直接产生内部类对象。
public class StaticClass {
static class Inner{
private int c = 30;
public void Test(){
System.out.println("静态内部类Inner的test方法");
}
}
}
public class Test {
public static void main(String[] args) {
StaticClass.Inner inner = new StaticClass.Inner();
inner.Test();
}
}
(2)由于在静态内部类中不依赖外部类对象,因为产生静态内部类时没有产生外部类对象
可以拥有静态域和成员域,但是不能访问外部类的成员域,因为没有外部类对象。可以访问外部类的私有静态域。
public class StaticClass {
private int a = 10;
private static int b = 20;
static class Inner{
public void Test(){
System.out.println(b);
StaticClass staticClass = new StaticClass();
System.out.println(staticClass.a);
System.out.println("静态内部类Inner的test方法");
}
}
public void fun(){
Inner inner = new Inner();
inner.Test();
}
}
能否调用一个类的属性和方法分两步:
首先检查访问修饰符,调用方法和属性位置,该属性和方法是否可见。
保持可见性的前提下在来来看是静态的还是成员的,成员域必须由对象调用。 111
(3)不管哪种内部类,内外部类的私有权限都是可见的。
静态内部类可以直接访问外部类的私有静态属性,成员属性需要通过外部类的对象调用。外部类可以通过内部类的对象来访问内部类的私有域,静态和非静态都可以。
public class StaticClass {
private int a = 10;
private static int b = 20;
static class Inner{
private int c = 30;
public void Test(){
System.out.println(b);
StaticClass staticClass = new StaticClass();
System.out.println(staticClass.a);
System.out.println("静态内部类Inner的test方法");
}
}public void fun() {
Inner inner = new Inner();
inner.Test();
System.out.println(inner.c);
}
public static void main(String[] args) {
StaticClass staticClass = new StaticClass();
staticClass.fun();
}
}
在主方法中创建StaticClass类的对象,调用fun函数,fun函数中创建Inner类的对象调用test函数和Inner类的成员变量c,然后再test函数中调用StaticClass中的成员变量a和b,但是调用a时需要建立StaticClass的对象,用对象调用,但是再调用静态成员变量b时可以直接调用。
另外两种方法在以后的学习中会提到。