面向对象【内部类】
1、概述
简单来说,内部类就是在一个类的内部进行其他类结构的嵌套的操作。
2、内部类访问规则
内部类访问规则:
内部类可以直接访问外部类中的成员
,但外部类不能直接访问内部类
,若要访问,必须创建内部类对象
才能访问。
public class Test {
public static void main(String[] args) {
Outer out = new Outer();
out.method();
}
}
class Outer{
//外部类的成员变量
int num = 5;
//写在Outer成员位置上的内部类
class Inner{
//内部类的成员函数
void show(){
//在内部类中访问外部类的成员变量
System.out.println("Outer num = "+num);
}
}
public void method(){
//创建内部类对象,访问内部类的成员函数或者变量
Inner in = new Inner();
in.show();
}
}
3、内部类的特点
- 内部类可以
直接访问外部类
的所有数据(包括私有数据); - 内部类可以使用对外部类之外的类进行隐藏(封装的一种);
- 使用内部类可以
实现多继承
; - 可以使用匿名内部类来代替大量的代码;
- 引入内部类后,程序结构会有些混乱。
4、内部类的分类
内部类一般来说包括四种:成员内部类、静态内部类、方法内部类、匿名内部类。
4.1、成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部。
class Outer{
//外部类的成员变量
int num = 5;
//写在Outer成员位置上的内部类
class Inner{
//内部类的成员函数
void show(){
//在内部类中访问外部类的成员变量
System.out.println("Outer num = "+num);
}
}
public void method(){
//创建内部类对象,访问内部类的成员函数或者变量
Inner in = new Inner();
in.show();
}
}
创建内部类对象,访问内部类方法
public class Test {
public static void main(String[] args) {
//通过创建外部类对象,接着创建内部类对象
Outer.Inner in = new Outer().new Inner();
in.show();
}
}
当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
4.2、静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static
。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法
。
class Outer{
//外部类的成员变量
static int num = 5;
//写在Outer成员位置上的静态内部类
static class Inner{
//内部类的成员函数
void show(){
//在内部类中访问外部类的成员变量
System.out.println("Outer num = "+num);
}
}
}
当内部类在外部类成员位置上被static修饰时,由于静态可以直接使用类名调用
。
public class Test {
public static void main(String[] args) {
//因为内部类是静态,所以不需要创建Outer的对象。直接创建内部类对象就哦了。
Outer.Inner in = new Outer.Inner();
in.show();
}
}
4.3、方法内部类
定义在外部类的方法中,也叫局部内部类。
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
注意
: 局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。
class Outer {
void method(){
//局部内部类
class Inner {
//局部内部类的成员函数
void show() {
System.out.println("Inner show");
}
}
//在局部内部类所在的外部类函数中创建局部内部类对象
Inner in = new Inner();
in.show();
}
}
当内部类在外部类的局部位置上时,这时在外部类以外的其他地方是无法创建局部内部类对象。只能在内部类所在的局部函数中创建对象,通过外部类调用内部类所在的函数从而执行内部类中的函数。
public class Test {
public static void main(String[] args) {
//创建外部类对象,调用method方法
Outer out = new Outer();
out.method();
}
}
4.4、匿名内部类
匿名内部类是唯一一种没有构造器的类,匿名内部类是直接使用new来生成一个对象的隐式引用,是内部类的简化形式。也就是没有名称的方法内部类。
在使用匿名内部类的过程中,我们需要注意如下几点:
-
使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
-
匿名内部类中是不能定义构造函数的。
-
匿名内部类中不能存在任何的静态成员变量和静态方法。
-
匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
-
匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
格式:new 父类or接口(){子类的内容 重写的方法}
interface Inter
{
void show1();
void show2();
}
class Outer
{
int num = 4;
//在一个类使用一个接口的对象。可以通过内部类来实现。
/* 这种方式有些麻烦,简化成匿名内部类实现
class Inner implements Inter
{
public void show1()
{}
public void show2()
{}
}
*/
public void method()
{
/*
Inner in = new Inner();
in.show1();
in.show2();
*/
//对其简化,写成匿名内部类的方式。
Inter in = new Inter()//记住:内部类中一般方法不要过多。阅读性会很差。
{
public void show1()
{}
public void show2()
{}
};
in.show1();
in.show2();
}
}
5、内部类与外部类的关系
- 对于非静态内部类,它的创建需要外部类的实例对象,如果没有外部类的实例,就无法创建内部类对象;
- 内部类是相对独立的;
- 内部类可以直接访问外部类的所有元素;
- 外部类不可以直接访问内部类的元素(可以间接访问)。