将一个类定义在另一个给类里面或者方法里面,这样的类就被称为内部类。相对而言, 包含它的类称为外部类.
内部类:
作为类:
1.可以继承父类,实现接口
2.类内部可以有类的成员(普通类可以做的事情内部类都可以)
作为类的成员:
1.可以被static修饰
2.可以使用四种权限修饰符、
3.内部类还可以调用外部类的成员(属性、方法)
学习目标:
1.如何创建内部类的对象?
静态内部类:new 外部类名.内部类名()
非静态内部类:外部类的对象.new 内部类名()
2.内部类如何调用外部类的成员(属性和方法)
静态内部类:外部类名.类变量名、静态方法(只能调用外部类的类变量和静态方法)
非静态内部类:外部类名.this.属性名、方法名
3.如何使用局部内部类
静态内部类
静态内部类与静态变量和静态方法定义的位置一样, 也带有关键字static.它的一般定义格式如下:
class 外部类{
static class 内部类{
//静态内部类的实现
}
}
静态内部类:
(1)与一个独立的类差别不大,可以有静态变量、静态方法、成员变量、成员方法、构造器等
(1)可以访问外部类的静态变量和方法, 但是不可以访问实例变量和方法.
(2)public 修饰的静态内部类可以通过"外部类.静态内部类"的方式被外部使用.
成员内部类:它定义在另一个类中
它的一般定义格式如下:class 外部类{
class 内部类{
//成员内部类的实现
}
}
内部类可以无条件访问外部类的属性和方法,但是如果外部类想要访问内部类中的属性或方法时,必须要创建一个内部类对象,然后通过该对象访问内部类的属性或方法。
(1)内部类访问外部类的方法和属性
public class Outer {
private String name = "我的名字是外部类";
String greet = "Hello";
public void outerMethod(){
System.out.println(greet+","+name);
}
class Inner{
public void innerMethod(){
System.out.println(name);
outerMethod();//成员内部类直接访问外部类的方法
}
}
public void test(){
Inner inner = new Inner();
inner.InnerMethod();//外部类使用内部类中的方法
}
}
(2)成员内部类在外部的使用
public class Outer {
private int a = 100;
public class Inner{
public void InnerMethod(){
System.out.println("Inner class");
}
}
public static void main(String[] args) {
Outer outer = new Outer();//创建外部类对象
Outer.Inner inner = outer.new Inner();//通过外部类对象创建非静态内部类对象
inner.InnerMethod();
}
}
(1)与静态内部类不同, 成员内部类对象总是和一个外部类对象相连的, 在外部使用时,他不能
直接通过new Outer.Inner()
的方式创建对象,而是先创建一个Outer类对象
,然后使用“外部类对象.new 内部类”
的方式创建内部类对象
(2)与静态内部类不同,成员内部类中不可以定义静态成员(final 变量例外,它等同于常量)
方法内部类
方法内部类定义在方法体中。它和成员内部类的区别在于局部内部类的访问权限仅限于方法或作用域内.class 外部类{
方法(){
class 局部内部类{
}
}
}
如何使用方法内部类?
(1)只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类
(2)但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型.
注:
(1)方法内部类可以使用外部方法的局部变量,但是必须是final的。由方法内部类和局部变量的声明周期不同所致。
(2)方法内部类和局部变量地位类似,不能使用public,protected,缺省,private
(3)方法内部类不能使用static修饰,因此也不能包含静态成员
匿名内部类
与前面介绍的内部类不同,匿名内部类没有单独的类定义,它在创建对象的同时定义类,语法如下:new 父类(参数列表){
//匿名内部类实现部分
}
或者
new 父接口(参数列表){
//匿名内部类实现部分
}
匿名内部类只能被使用一次, 用来创建一次. 它没有名字, 没有构造方法, 但可以根据参数列表, 调用对应的父类构造方法. 与方法内部类一样, 匿名内部类也可以访问外部类的所有变量和方法, 可以访问方法中的final 参数和局部变量.
abstract class Computer{
public abstract void info();
}
class SuperClass{
public void show(){
System.out.println("superClass");
}
}
public class AnonymousTest2 {
public static void main(String[] args) {
//创建了一个Computer匿名子类的对象
Computer c = new Computer(){
@Override
public void info() {
System.out.println("c info");
}
};
test(c);
System.out.println("----------创建普通类的匿名子类------------");
//创建了一个SuperClass匿名子类的对象
SuperClass sc = new SuperClass(){
@Override
public void show(){
System.out.println("subClass");
}
};
sc.show();
}
public static void test(Computer c){
c.info();
}
}
输出结果
c info
----------创建普通类的匿名子类------------
subClass