4.3 Java进阶(三)内部类

一、内部类的概述

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、在静态内部类中可以存在静态成员和非静态的成员,静态内部类只能访问外部类的静态成员变量和方法,不能访问外部类的非静态成员变量和方法。

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();
}


猜你喜欢

转载自blog.csdn.net/qq_40254536/article/details/81013698
4.3
今日推荐