Java内部类:就是讲一个类定义另一个类的内部
内部类的特点:
1.可以很好的实现隐藏,使用protected,private关键字修饰
2.内部类可以直接访问外部类的所有成员,包括私有成员
3.外部类不能直接访问内部类成员,必须首先建立内部类的对象才可以访问
4.内部类可以解决一些问题,例如间接实现多继承,可以避免修改接口而实现同一个类中的两种同名方法的调用
内部类分类:
1.成员内部类
2.静态内部类
3.匿名内部类
4.局部内部类
1.成员内部类
成员内部类属于外部类的实例成员,成员内部类可以有public private default protected修饰,在成员内部类中访问外部类的成员方法和属性,要使用”外部类名.this.成员方法“和”外部类名.this.成员属性“的形式来访问。
创建成员内部类格式:外部类名 外部类实例变量名 = new 外部类名();
外部类名.内部类名 内部类实例变量名 = 外部类实例变量名.new 内部类名();
成员内部类的限制:
1.成员内部类不能与外部类重名
2.不能在成员内部类中定义static属性,方法和类(static final 常量定义除外)
下面是一个例子:
package com.pyj.inner;
public class MemberInnerClass {
public static void main(String[] args) {
// 创建外部类的对象
Outer outer = new Outer();
outer.outerShow();
// 创建内部类对象
Outer.Inner inner = outer.new Inner();
inner.innerShow();
}
}
// 定义一个外部类
class Outer {
private String name = "张三";
private int age1 = 18;
public void outerShow() {
System.out.println(name + "====" + age1);
}
// 内部类
public class Inner {
private String name = "李四";
private int age2 = 20;
public void innerShow() {
System.out.println(name + "=======" + age2);
}
}
}
2.静态内部类
静态内部类的特点:
1.使用static修饰成员内部类叫静态内部类
2.静态内部类跟外部类没有任何关系,只是在生成类名和类定义时有影响
3.静态内部类可以看做是外部类的平级类,使用方式与外部类完全相同
创建静态内部类格式:外部类名.内部类名 实例名 = new 内部类名();
或者 外部类名.内部类名 实例名 = new 内部类名.外部类名();
静态内部类限制:
1.不能重名
2.静态内部类不能访问外部类非静态的属性和方法,外部类不能访问内部类的非静态的属性和方法
实例如下:
package com.pyj.inner;
import com.pyj.inner.Outer1.Inner1;
public class StaticInnerClass {
public static void main(String[] args) {
//构造一个静态内部类对象
//Outer1.Inner1 inner = new Inner1();
//inner.innerShow();
Outer1.Inner1 inner = new Outer1.Inner1();
inner.innerShow();
Outer1 out = new Outer1();
out.outerShow();
}
}
//创建一个外部类
class Outer1{
private String name = "张三";
private int age1 = 18;
private static int age3 = 100;
public void outerShow() {
System.out.println(name+"==="+age1);
//访问静态类中非静态属性需要实例化
Inner1 inner = new Inner1();
System.out.println(inner.name);
//访问静态属性,直接类名.属性
System.out.println(Inner1.age3);
}
public static class Inner1{
private String name = "李四";
private int age2 = 20;
private static int age3 = 300;
public void innerShow() {
//System.out.println(Outer.this.name);
//静态内部类不能访问外部类的非静态成员
System.out.println(Outer1.age3);
System.out.println(name+"==="+age2);
}
}
}
3.匿名内部类
匿名内部类特点:
1.匿名内部类是没有名称的内部类,没有办法引用他们,必须在创建时作为new语句的一部分来声明并创建他们的实例。
2.匿名内部类必须继承一个类(抽象,非抽象,接口)
3.匿名内部类可以定义代码块,用于实现初始化,但是不能定义静态代码块
语法格式:new interface/superclass{//类实体}
具体实现如下:
package com.pyj.inner;
public class AnonymousInnerClass {
public static void main(String[] args) {
Person p = new Person();
new IAnimal() {
@Override
public void eat() {
//抽象类中的抽象方法
System.out.println("吃饭");
}
//接口或者抽象类中没有的方法
public void show() {
System.out.println("小明");
}
}.show();//匿名内部类调用内部方法
p.feed(new IAnimal() {
@Override
public void eat() {
System.out.println("吃肉");
}
});
}
}
//创建一个人,会喂食动物的方法,动物可以使用接口或者抽象类来实现
class Person{
public void feed(IAnimal animal) {
animal.eat();
}
}
interface IAnimal{
public abstract void eat();
}
/*abstract class Animal{
public abstract void eat();
}*/
4.局部内部类
局部内部类特点:
1.定义在代码块,方法体内的类叫局部内部类
2.局部内部类访问外部类的属性和方法
外部类名.this.属性名
外部类名.this.方法名(参数)
3.对外部完全隐藏,只能在作用域内生成对象
限制:
1.局部内部类不能加访问修饰符,因为它不是类成员
2.不能与外部类重名
3.局部内部类访问作用域内的局部变量需要使用final修饰
例子如下
package com.pyj.inner;
public class LocalInnerClass {
}
//创建一个外部类
class Outer2{
private String name = "张三";
private int age1 = 18;
private static int age2 = 100;
public void outerShow() {
final int age4 = 1000;
//局部内部类不能添加访问修饰符
class Inner2{
private int age1 = 20;
private int age3 = 30;
public void innerShow() {
System.out.println(age3);
System.out.println(age1);
//访问外部非静态变量
System.out.println(Outer2.this.age1);
//访问外部静态变量
System.out.println(Outer2.age2);
//局部内部类只能访问其声明方法中的常量
System.out.println(age4);
}
}
Inner2 inner = new Inner2();
inner.innerShow();
}
}