内部类

内部类:定义在其他类内部的类
外部类:包含内部类的类


内部类:
1.成员内部类
⑴静态内部类
⑵非静态内部类
2.局部内部类


优点;
1.提供了更好的封装,把内部类隐藏在外部类中,不允许同一个包中的其他类访问该类;
2.内部类成员可直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问;
3.外部类不能访问内部类的实现细节,如成员变量;
4.匿名内部类适合用于创建仅需要一次使用的类;
5.内部类比外部类可以多使用三个修饰符:public,protected,static——外部类不可以使用
6.非静态内部类不能拥有静态成员。


非静态内部类

内部类定义:在类中的任何位置都可以,包括在方法中(在方法里定义个内部类被称为局部内部类);
当调用非静态内部类的实例方法时,必须有一个非静态内部类的实例,这个实例必须寄生在外部类的实例里;

外部类静态成员不能访问非静态内部类;

public class Cow {
	
	private double weight;
	public Cow(){};
	public Cow(double weight)
	{
		this.weight = weight;
	}
	
	private class CowLeg
	{
		private double length;
		private String color;
		
		public CowLeg(){}
		public CowLeg(double length,String Color)
		{
			this.length = length;
			this.color = Color;
		}
		public double getLength() {
			return length;
		}
		public void setLength(double length) {
			this.length = length;
		}
		public String getColor() {
			return color;
		}
		public void setColor(String color) {
			this.color = color;
		}
		
		public void info()
		{
			System.out.println("颜色:"+color+";高:"+length);
			
			System.out.println("体重:"+weight);
		}
	}
	
	public void test()
	{
		CowLeg cl = new CowLeg(1.12,"黑白相间");
		cl.info();
	}
	
	public static void main(String[] args) {
		Cow cow = new Cow(666);
		cow.test();
	}
}
/*	输出结果:
	颜色:黑白相间;高:1.12
	体重:666.0
*/

public class DisVar {
	
	private String prop = "外部类的实例变量";
	
	private class inclass
	{
		private String prop = "内部类的实例变量";
		public void inof()
		{
			String prop = "局部变量";
			System.out.println(DisVar.this.prop);
			System.out.println(this.prop);
			System.out.println(prop);
		}
	}
	
	public void test()
	{
		inclass in = new inclass();
		in.inof();
	}


	public static void main(String[] args) {
		new DisVar().test();
	}


}


/*输出结果:
外部类的实例变量
内部类的实例变量
局部变量
*/

如果外部类要访问非静态内部类的成员,必须显示创建非静态内部类对象来调用访问其实例成员。
public class Outer {
	private int out = 9;
	
	class Inner
	{
		private int in = 5;
		
		public void toOut()
		{
			System.out.println(out);
		}
	}
	
	public void toIn()
	{
		//System.out.println(in); 报错
		System.out.println(new Inner().in);
	}
	public static void main(String[] args) {
		Outer o = new Outer();
		o.toIn();
	}
}



静态内部类

如果使用static修饰一个内部类,则成为静态内部类,这个内部类就属于外部类本身,而不属于外部类的某个对象;

静态内部类可以包含静态成员,也可以包含非静态成员,由于静态成员不能访问非静态成员,故静态内部类不能访问外部类的实例成员,只能访问外部类的类成员;

静态内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员。

public class StaticInner
{
    private int p = 5;
    private static int m = 2;
    
    static class staIn{
        private static int age;
        
        public void toOut()
        {
            //System.out.println(p);   报错
            System.out.println(m);
        }
    }
}


静态内部类是外部类的一个静态成员,因此外部类的静态方法,静态代码块中可以使用静态内部类来定义变量,创建对象;
public class Access
{
    static class StaticInner
    {
        private static int p = 5;
        private int m = 2;
    }
    
    public void access()
    {
        //System.out.println(p);  报错
        
        System.out.println(StaticInner.p);
        
        //System.out.println(m);  报错
        
        System.out.println(new StaticInner().m);
    }
}

接口里也可以定义内部类,用public static修饰;

使用内部类

外部类以外地方定义内部类:
OuterClass.InnerClass varName


1.在外部类中使用内部类

2.在外部类外使用非静态内部类
OuterInstance.new InnerConstructor()


如果要在外部类以外的地方访问内部类,则内部类不能使用private修饰,private修饰的内部类只能在外部类中使用;
省略访问控制符,只能被与外部类处于同一包中的其他类访问;
使用protect修饰的内部类,可被与外部类处于同一包中的其他类和外部类的子类所访问;
使用public修饰的内部类,可以在任何地方被访问;
class Out
{
    class In
    {
        public In(String s)
        {
            System.out.println(s);
        }
    }
}

public class CreateInner
{
    public static void main(String[] args)
    {
        Out.In in = new Out().new In("Hello");
        
        /*Out.In in;
        Out out = new Out();
        in = out.new In("hehe");*/
    }
}


3.在外部类外使用静态内部类
在外部类以外的地方创建静态内部类实例语法:
new OuterClass.InnerConstrustor();
class Out
{
    static class StaticIn
    {
        public StaticIn()
        {
            System.out.println("静态内部类的构造器");
        }
    }
}

public class test
{
    public static void main(String[] args)
    {
        Out.StaticIn in = new Out.StaticIn();
        
        //Out.StaticIn in;
        //in = new Out.StaticIn();
    }
}



局部内部类

把一个内部类放在方法里定义,局部内部类仅在该方法里有效,局部内部类不能在外部类的方法以外的地方使用,故不能使用访问控制符和static修饰;

局部内部类的上一级程序单元是方法,不是类;
public class LocalInnerClass
{
    public static void main(String[] args)
    {
        class InnerBase
        {
            int a;
        }
        
        class InnerSub extends InnerBase
        {
            int b;
        }
        
        InnerSub is = new InnerSub();
        
        is.a = 5;
        is.b = 6;
        System.out.println(is.a + " " + is.b);
    }
}


匿名内部类

匿名内部类适合创建那种只需要一次使用的类,创建匿名内部类时会创建一个该类的实例,这个类定义即消失,不能重复使用;
格式:
new 父类构造器(实参列表)|实现接口()
{
         //匿名内部类的类体部分
}
匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类或实现一个接口。
规则:
1.匿名内部类不能是抽象类;
2.匿名内部类不能定义构造器,因为没有类名,若是接口,括号里也不能有参数;可以定义实例初始化块来完成构造器需要完成的事情;

3.匿名内部类需要访问外部类的局部变量,必须用final来修饰外部类的局部变量。

interface Product
{
    public double getPrice();
    public String getName();
}

public class Test
{
    public void test(Product p)
    {
        System.out.println("Price: "+ p.getPrice() + " Name: " + p.getName());
    }
    
    public static void main(String[] args)
    {
        Test t = new Test();
        
        t.test(new Product()
        {
            public double getPrice()
            {
                return 100;
            }
            
            public String getName()
            {
                return "hehe";
            }
        });
    }
}

继承父类:

abstract class Device
{
    private String name;
    public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public abstract double getPrice();
    public Device(){};
    public Device(String name)
    {
        this.name = name;
    }
}

public class Outer
{
    public void test(Device p)
    {
        System.out.println("Price: "+p.getPrice()+"  Name: "+p.getName());
    }
    
    public static void main(String[] args)
    {
        Outer t = new Outer();
        t.test(new Device("hehe")
        {
            public double getPrice()
            {
                return 6.21;
            }
        });
        
        Device d = new Device()
        {
            //初始化块
            {
                System.out.println("匿名内部类的初始化块");
            }
            //实现抽象方法
            public double getPrice()
            {
                return 55.5;
            }
            
            public String getName()
            {
                return "whoami";
            }
        };
        t.test(d);
    }
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值