一、内部类的概述
1、内部类,就是在一个类的内部在定义一个类。
2、分类:静态内部类、成员内部类、局部内部类、匿名内部类
3、内部类的简单应用:
(1)新建一个外部类Outer,在Outer里写一个内部类Inter
public class Outer {
private int id=1001;
private String name="admin";
public void py()
{
System.out.println(id+"\t"+name);
}
public class Inter
{
public void play()
{
py(); //调用方法不可与本方法同名
}
}
}
(2)声明内部类Inter方法一
public void test01()
{
Outer.Inter oi=new Outer().new Inter();
oi.play();
}
//输出结果【1001 admin】
(3)声明内部类Inter方法二
public void test02()
{
Outer o=new Outer();
Outer.Inter oi=o.new Inter();
oi.play();
}
//输出结果【1001 admin】
二、内部类的实际应用
1、在User类中定义两个内部类,分别是Teacher、Student,并添加带参构造方法
public class User {
private int id;
private String name;
private String sex;
private String address;
private String birth;
private String phone;
public User(int id, String name, String sex, String address, String birth, String phone) {
this.id = id;
this.name = name;
this.sex = sex;
this.address = address;
this.birth = birth;
this.phone = phone;
}
public void play(){
System.out.println(id+"\t"+name+"\t"+sex+"\t"+address+"\t"+birth+"\t"+phone);
}
//内部类Teacher
public class Teacher
{
int teaAge;
public Teacher(int teaAge)
{
this.teaAge = teaAge;
}
public void show()
{
play(); //调用方法不可与本方法同名
System.out.println(teaAge);
}
}
//内部类Teacher
public class Student
{
int pop;
public Student(int pop) {
this.pop = pop;
}
public void show()
{
play();
System.out.println(pop);
}
}
}
2、调用内部类
public void test03()
{
User u=new User(1001,"张三","男","广东广州","1990-02-14","15018743146");
User.Teacher teacher=u.new Teacher(7);
teacher.show();
}
//输出结果【1001 张三 男 广东广州 1990-02-14 15018743146 7】
三、静态内部类
1、静态内部类可以用public,protected,private,默认访问权限修饰。
2、在静态内部类中可以存在静态成员和非静态的成员,静态内部类只能访问外部类的静态成员变量和方法,不能访问外部类的非静态成员变量和方法。
扫描二维码关注公众号,回复:
2139539 查看本文章
3、非静态内部类中不能存在静态成员,非静态内部类中可以调用外部类的任何成员,不管是静态的还是非静态的。
4、代码示例:
public class StaticOuter
{
@SuppressWarnings("unused")
private String sex;
public static String name = "chenssy";
/**
*静态内部类可以用public,protected,private,默认访问权限修饰
*/
static class InnerClass1
{
int inner_i = 100;
public static String name1 = "chenssy_static"; //在静态内部类中可以存在静态成员和非静态的成员
public void display()
{
System.out.println("OutClass name :" + name); //静态内部类只能访问外部类的静态成员变量和方法, 不能访问外部类的非静态成员变量和方法
}
}
/**
* 非静态内部类
*/
class InnerClass2
{
public String name2 = "chenssy_inner"; //非静态内部类中不能存在静态成员
public void display(){
System.out.println("OuterClass name:" + name); //非静态内部类中可以调用外部类的任何成员,不管是静态的还是非静态的
}
}
/**
* 外部类方法
*/
public void display()
{
System.out.println(InnerClass1.name1); //外部类可以直接访问静态内部类的静态成员:[内部类.静态成员]
new InnerClass1().display(); //静态内部类可以直接创建实例不需要依赖于外部类, 外部类访问内部类的非静态成员,实例化内部类即可
StaticOuter.InnerClass2 inner2 = new StaticOuter().new InnerClass2(); //非静态内部的创建需要依赖于外部类
System.out.println(inner2.name2); //访问非静态内部类的成员需要使用非静态内部类的实例
inner2.display();
}
public static void main(String[] args)
{
StaticOuter outer = new StaticOuter();
outer.display();
}
/*
* 输出结果:
* chenssy_static
OutClass name :chenssy
chenssy_inner
OuterClass name:chenssy
*/
}
四、成员内部类
1、成员内部类中不能存在任何static的变量,static方法和static代码块
2、成员内部类是依附于外部类的,所以只有先创建了外部类才能够创建内部类。
3、代码示例:
public class MemberOuter
{
private static int i = 1;
private int j = 10;
private int k = 20;
public static void outer_f1()
{
}
public void outer_f2()
{
}
class Inner
{
// static int inner_i = 100;
//成员内部类中不允许定义静态成员
int j = 100; //内部类和外部类的变量可以同名
int inner_i = 1;
void inner_f1()
{
System.out.println(i); // 成员内部类中,可以访问外部类的所有成员
System.out.println(j); //在内部类中访问内部类自己的变量直接用变量名
System.out.println(this.j); //在内部类中访问内部类自己的变量也可以用this.变量名
System.out.println(MemberOuter.this.j); //在内部类中访问外部类中与内部类同名的实例变量用外部类名.this.变量名
System.out.println(k); //如果内部类中没有与外部类同名的变量,则可以直接用变量名访问外部类变量
outer_f1(); //成员内部类中,可以访问外部类的所有成员
outer_f2(); //成员内部类中,可以访问外部类的所有成员
}
}
//外部类的非静态方法访问成员内部类(和使用普通类没什么区别)
public void outer_f3()
{
Inner inner = new Inner();
inner.inner_f1();
}
// 外部类的静态方法访问成员内部类,与在外部类的外部访问成员内部类一样,应该具体的指出这个对象的类型:OuterClassName.InnerClassName
public static void outer_f4()
{
//step1 建立外部类对象
MemberOuter out = new MemberOuter();
//step2 根据外部类对象建立内部类对象
Inner inner = out.new Inner();
//step3 访问内部类的方法
inner.inner_f1();
}
public static void main(String[] args) {
//outer_f4(); //该语句的输出结果和下面三条语句的输出结果一样
//如果要直接创建内部类的对象,不能想当然地认为只需加上外部类Outer的名字就可以按照通常的样子生成内部类的对象,而是必须使用此外部类的一个对象来创建其内部类的一个对象
//Outer.Inner outin = out.new Inner(); //这是错的
//因此,除非你已经有了外部类的一个对象,否则不可能生成内部类的对象。因为此内部类的对象会悄悄地链接到创建它的外部类的对象。如果你用的是静态的内部类,那就不需要对其外部类对象的引用。
MemberOuter out = new MemberOuter();
MemberOuter.Inner outin = out.new Inner();
outin.inner_f1();
}
/*
* 输出结果:
* 1
100
100
10
20
*/
}
五、局部内部类
public class PartOuter
{
@SuppressWarnings("unused")
private void internalTracking(boolean b)
{
if(b)
{
class TrackingSlip
{
private String id;
TrackingSlip(String s)
{
id = s;
}
String getSlip()
{
return id;
}
}
TrackingSlip ts = new TrackingSlip("chenssy");
String string = ts.getSlip();
}
}
public void track(){
internalTracking(true);
}
public static void main(String[] args)
{
PartOuter parcel = new PartOuter();
parcel.track();
}
}
六、匿名内部类
1、匿名内部类就是没有名字的内部类。
2、使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口, 当然也仅能只继承一个父类或者实现一个接口。
3、如果满足下面的一些条件,使用匿名内部类是比较合适的:
(1)只用到类的一个实例。
(2)类在定义后马上用到。
(3)类非常小(推荐是在4行代码以下)
(4)给类命名并不会导致你的代码更容易被理解。
4、代码示例:
public class AnOuter
{
public InnerClass getInnerClass(final int num,String str2)
{
return new InnerClass()
{
int number = num + 3;
public int getNumber(){
return number;
}
}; /* 注意:分号不能省 */
}
public static void main(String[] args)
{
AnOuter out = new AnOuter();
InnerClass inner = out.getInnerClass(2, "chenssy");
System.out.println(inner.getNumber());
} //输出结果【5】
}
interface InnerClass
{
int getNumber();
}