内部类:
定义:匿名内部类是定义在外部类内部的类
分类 (1)有名内部类
(2)匿名内部类
Eg:有名内部类:
public calss Body{
//有名内部类
public class Heart{
public void beat(){
System.out.println("......");
}
}
}
Eg:匿名内部类:匿名内部类由于没有类名而不能单独存在,定义匿名内部类的同时,必须直接实例化该类
new 父类构造器([参数列表])|接口(){
//匿名内部类类体
}
普通匿名类实质为普通类的子类
class Mammal{
public void move(){
System.out.println("......");
}
}
public cladd Sea{
//调用上边类中的无参构造方法
Mammal mammal = new Mallal(){
@Override
public void move(){
System.out.println("......");
}
}
}
匿名内部类的特点:
(1)匿名内部类一定是接口的实现类,或者是普通类或抽象类的子类
(2)匿名内部类不能有构造方法
(3)匿名内部类一定不是抽象类
(4)可以在匿名内部类中添加新的属性和方法但这些属性和方法不能被上转型调用,只能被非上转型对象方式创建的匿名内部类对象所调用,例如:
//正确
public class Test{
public static void main(String[] args){
new IMamml(){
public void breath(){
System.out.println("......1");
}
public void move(){
System.out.println("......2");
}
}.breath(); //调用新增的内部方法,一次只能调用一个
}
}
interface IMammal{
void move();
}//警告不能有个上转型对象昂调用内部类新增的方法
静态内部类:按照是否有satic区分:分为静态有名内部类,非静态内部类
静态有名内部类:
package com.jd;
//外部类
public calss Body{
//静态内部类
public static class Heart{
public static void main(String[] args){
//跨类使用则需:外部类类名+内部类类名
Heart heart = new Body.Heart();
heart.beat();
}
}
}
}
静态匿名内部类:
class Father{
puvlic void eat(){
Syste,out.println("......1");
}
}
//外部类
public calss OutClass{
//匿名静态内部类
static Father son = new Father(){
public void eat(){
System.out.println("....");
}
}
}
!!!!!!:如果为static内部类只能直接定义在外部类中,静态内部类只能直接访问外部类的静态成员变量方法,可以通过创建外部类的对象直接使用非成员变量和方法
在非外部类中定义的内部类和局部变量一样,其适用范围从定义的位置开始到其所在直接语句结束
public class OutClass{
public static void main(String[] args){
if(args !==null){
class InClass{
}
}
//程序出错因为内部类作用范围无法到达这里
InClass inClass = new InClass();
}
}
只有有名静态内部类中才允许有静态成员(静态属性,静态代码,静态方法)
内部类特点:
内部类是一个独立的类:编译之后内部类会被编译成独立的.class文件,如果该内部类为有名内部类,则有名内部类字节码文件名为外部类的类名+$+内部类类名;如果为匿名内部类,则匿名内部类字节码文件名为外部类的类名+$+数字;
普通外部类、抽象类和接口可以有内部类(匿名的或有名的);
内部类可以直接定义在类中,也可以定义在方法或代码块中;其中直接定义在外部类中的内部类可以有public、protected、默认的和private四种访问权限修饰(普通外部类、接口和抽象类只能使用public和default修饰),也可以使用static修饰( static不能修饰普通外部类、接口和抽象类);但是定义在方法或代码块中的内部类不能有访问修饰符修饰,也不能有static修饰。
内部类可以访问外部类的所有访问权限的成员变量