内部类
内部类的概念:将类定义类的内部,那么该类就成为内部类
注意: 内部类是一个相对的概念: 如果A类中有一个B类,那么A类相对于B类来说就是外部类,那么B类相对于A类来说就是内部类
内部类的分类
1.局部内部类
2.成员内部类
3.静态内部类
4.匿名内部类
内部类的特点
1.内部类可以直接访问外部类的私有成员吗? 可以
2.外部类可以访问内部类的成员? 必须创建内部类的对象
3.编译器编译生成字节码文件,格式是 : 外部类类名$内部类类名.class
4.但是内部类有一个缺陷,会造成类和类的耦合性过高。
public class InnerClassDemo01 {
public static void main(String[] args) {
}
}
class Outer{
private int num = 10;
// 成员内部类
class Inner{
public int num2 = 20;
public void show() {
System.out.println(num);
}
}
public void test() {
Inner inner = new Inner();
System.out.println(inner.num2);
inner.show();
}
// 静态内部类
static class Inner2{
}
public void show() {
// 局部内部类
class Inner3{
}
// 匿名内部类
new Inter() {
@Override
public void show() {
System.out.println("show");
}
}.show();
new Inter() {
@Override
public void show() {
System.out.println("show2");
}
};
}
}
interface Inter {
void show();
}
成员内部类
1.内部类可以直接访问外部类成员
2.外部不能直接访问内部类,需要创建内部类对象通过内部类对象来访问内部类成员
3.外界如需访问内部类成员则需要创建内部类对象:外部类类名.内部类类名 对象 = new 外部类对象.new 内部类对象
4.外界无法访问内部类私有成员需要内部类提供对外的公共访问方式
5.当外部类和内部类成员重名的时候外部类类名.this.外部类成员来访问外部类成员
public class InnerClassDemo02 {
public static void main(String[] args) {
// Outer2 outer2 = new Outer2();
// Outer2.Inner oi = new Outer2().new Inner();
// System.out.println(oi.num);
// System.out.println(outer2.num);
Outer2.Inner oi = new Outer2().new Inner();
oi.show();
}
}
class Fu {
int num = 5;
}
class Outer2 extends Fu{
int num = 10;
// 成员位置
class Inner{
int num = 20;
public void show() {
int num = 30;
System.out.println(num); // 30
System.out.println(this.num); // 20
System.out.println(Outer2.this.num); // 10
System.out.println(Outer2.super.num); // 5
}
}
public void show() {
}
}
局部内部类
在局部位置创建内部类对象,访问内部类成员案例
在JDK1.8之前,如果局部内部类访问外部类成员,需要加final关键字
public class InnerClassDemo04 {
public static void main(String[] args) {
Outer3 o = new Outer3();
o.show();
}
}
class Outer3 {
int a = 20;
public void show() {
int x = 100;
class InnerX {
int num = 10;
public void show() {
System.out.println(num);
System.out.println(a);
}
}
InnerX innerX = new InnerX();
System.out.println(innerX.num);
innerX.show();
}
public void method() {
}
}
静态内部类
静态内部类中可以有静态成员和非静态成员
访问非静态成员需要创建对象
访问静态成员可以直接调用 :外部类类名.内部类类名.静态成员
访问静态内部类格式: 外部类类名.内部类类名 对象 = new 外部类对象.内部类类名();
public class InnerClassDemo05 {
public static void main(String[] args) {
//访问静态内部类格式: 外部类类名.内部类类名 对象 = new 外部类对象.内部类类名();
Outer4.Inner oi = new Outer4.Inner();
System.out.println(oi.num);
System.out.println(oi.num2);
oi.show();
oi.method();
Outer4.Inner.num2 = 200;
Outer4.Inner.method();
}
}
class Outer4 {
static class Inner {
public int num = 10;
public void show() {
System.out.println("Outer4.Inner.show()");
}
public static int num2 = 20;
public static void method() {
System.out.println("Outer4.Inner.method()");
}
}
interface Entry {
}
}
匿名内部类
概念: 本质就是一个子类匿名对象
特点:
1.是一个子类匿名对象 父类 可以是 普通类 抽象类 接口
2.是一个对象
3.没有名字的子类 前提条件: 存在一个父类(接口 /抽象类/普通类)
格式:
new 类名/接口名(){
//重写方法
}
public class InnerClassDemo06 {
public static void main(String[] args) {
new Student() {
};
new AbsTeacher() {
@Override
void teach() {
// TODO Auto-generated method stub
}
};
new ICar() {
@Override
public void run() {
// TODO Auto-generated method stub
}
};
IDailup dailup = new IDailup() {
@Override
public void show2() {
// TODO Auto-generated method stub
}
@Override
public void show() {
// TODO Auto-generated method stub
}
};
dailup.show();
dailup.show2();
}
}
class CarImpl implements ICar{
@Override
public void run() {
System.out.println("CarImpl.run()");
}
}
interface ICar {
void run();
}
interface IDailup{
void show();
void show2();
}
abstract class AbsTeacher{
abstract void teach();
}
class Student{
public void show() {
System.out.println("Student.show()");
}
}