面向对象——内部类

18.面向对象——内部类(在一定程度打破类的定义,但在一些较复杂的类的设计中,内部类解决了java不能多继承的问题)

1 .成员内部类:直接在类中使用

成员内部类格式如下:

class Outer{
  class Inner{}
}

编译上述代码会产生两个文件:Outer.class和Outer$inner.class

package oo_01;

//内部类
/*
 * 成员内部类
 */

public class inner {

	public static void main(String[] args) {
		Outer outer=new Outer();
		//在外部创建成员内部类的实例需要依赖外部类的对象;
		//通常情况下,我们不建议这样来实例化对象
		Outer.Inner inner=outer.new Inner();
		inner.print();
	}
}
class Outer{
	private String name;
	 
	//成员内部类 
	class Inner{
		public void print() {
			System.out.println("inner");
		}
	}
}

通常情况我们不用实例化内部对象,建议在外部类中定义一个方法,对外提供访问类的接口

public class inner {

	public static void main(String[] args) {
		Outer outer=new Outer();
		//在外部创建成员内部类的实例需要依赖外部类的对象;
		//通常情况下,我们不建议这样来实例化对象
		//Outer.Inner inner=outer.new Inner();
		//inner.print();
		outer.innerPrint();
	}
}
class Outer{
	private String name;
	public void innerPrint() {
		Inner inner=new Inner();
		inner.print();
	} 
	//成员内部类 
	private class Inner{
		public void print() {
			System.out.println("成员内部类");
		}
	}
}

2.方法内部类:把类放在方法内定义

格式如下:

class Outer{
     public void doSomething(){
	 class inner{
		public void seeOuter(){}
		}
	}
}
  • 注意
  • [1] 方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外实例化
  • [2 ]方法内部类对象不能使用该内部类所在方法的非final局部变量。

[1]

public class inner {

	public static void main(String[] args) {
		Outer outer=new Outer();	
		outer.show();
	}
}	
//~~~~~~~~~方法内部类~~~~~~~~
	public void show() {
		 class Inner2{
			 public void print() {				 
					System.out.println("方法内部类");
			 }			 
		 }
		 Inner2 inner2=new Inner2();
		 inner2.print();
	}	
}

【2】

public void show(final int i) {
		final int x=10;
		 class Inner2{
			 public void print() {
				 //x++//从内部类引用的本地变量必须是最终变量或实际最终变量
					System.out.println("方法内部类"+x);
			 }			 
		 }
		 Inner2 inner2=new Inner2();
		 inner2.print();
	}

3.静态内部类:在一个类的内部定义一个静态内部类

静态的含义是内部可以像其他静态成员一样,没有外部类对象时,也能访问。静态嵌套类仅能访问外部类的静态成员和方法(无法从静态上下文中引用非静态变量)

//~~~~~~~~~静态内部类~~~~~~~~	
	static class Inner3{
		public void print() {
			System.out.println("静态内部类");
		}
	}

4匿名内部类

匿名内部类就是没有名字的内部类。
匿名内部类的三种情况
(1)继承式匿名内部类
(2)接口式匿名内部类
(3)参数式匿名内部类
在使用匿名内部类时,要记住以下几个原则:
(1)不能有构造方法,只能有一个实例
(2)不能定义如何静态变量,静态方法
(3)不能是public,protected,private,static。
(4)一定是在new的后面,用隐含实现一个接口活实现一个类
(5)匿名内部类为局部的,所以局部内部类的所有限制都对其生效

//继承式
	public void print2(){		
		Cat cat=new Cat() {     //对Cat进行实现,abstract不可以new
			public void eat() {
				System.out.println("eat:继承式匿名内部类");
			}
		};
		cat.eat();
	}
	//接口式
	public void print3() {
		Eat eat=new Eat() {
			public void eat() {
				System.out.println("eat:接口式匿名内部类");
			}
		};
		eat.eat();
	}
	
	//参数式
	public void print4(Eat eat) {
		eat.eat();
	}
}

interface Eat{
	public  void eat();
}
abstract class Cat{
		public abstract void eat();
	}

参数类的调用为

//参数式匿名内部类
		outer.print4(new Eat() {
			public void eat() {
				System.out.println("参数式匿名内部类");
			}
			});
		}	

完整代码

package oo_01;

//内部类
/*
 * 成员内部类:直接在类中定义的类
 * 方法内部类:在一个类中的方法内定义
 */

public class inner {

	public static void main(String[] args) {
		Outer outer=new Outer();
		//在外部创建成员内部类的实例需要依赖外部类的对象;
		//通常情况下,我们不建议这样来实例化对象
		//Outer.Inner inner=outer.new Inner();
		//inner.print();
		outer.innerPrint();
		outer.show();
		
		Outer.Inner3 inner3=new Outer.Inner3();
		inner3.print();
		
		outer.print2();
		outer.print3();
		
		//参数式匿名内部类
		outer.print4(new Eat() {
			public void eat() {
				System.out.println("参数式匿名内部类");
			}
			});
		}	
}
class Outer{
	private String name;
	//~~~~~~~~~成员内部类~~~~~~~~	
	
	//建议在外部类中定义一个方法,对外提供访问类的接口
	public void innerPrint() {
		Inner inner=new Inner();
		inner.print();
	} 
	//成员内部类 
	private class Inner{
		public void print() {
			System.out.println("成员内部类");
		}
	}
	
//~~~~~~~~~方法内部类~~~~~~~~
	
	public void show() {
		final int x=10;
		 class Inner2{
			 public void print() {
				 //x++//从内部类引用的本地变量必须是最终变量或实际最终变量
					System.out.println("方法内部类"+x);
			 }			 
		 }
		 Inner2 inner2=new Inner2();
		 inner2.print();
	}
	
	
	
//~~~~~~~~~静态内部类~~~~~~~~	
	static class Inner3{
		public void print() {
			System.out.println("静态内部类");
		}
	}

	

//~~~~~~~~~匿名内部类~~~~~~~~	
	//继承式
	public void print2(){		
		Cat cat=new Cat() {     //对Cat进行实现,abstract不可以new
			public void eat() {
				System.out.println("eat:继承式匿名内部类");
			}
		};
		cat.eat();
	}
	//接口式
	public void print3() {
		Eat eat=new Eat() {
			public void eat() {
				System.out.println("eat:接口式匿名内部类");
			}
		};
		eat.eat();
	}
	
	//参数式
	public void print4(Eat eat) {
		eat.eat();
	}
}

interface Eat{
	public  void eat();
}
abstract class Cat{
		public abstract void eat();
	}

在这里插入图片描述
内部类的作用
每一个内部类都能独立的继承自一个(接口)实现,所以无论外部类是否已经继承了某个(接口)实现,对于内部类都没有影响,如果没有内部类提供的可以多个具体的或抽象的类的能力,一些设计和编程问题就难已解决。从这个角度看,内部类使得多重继承的解决方法变得完整,接口解决了部分问题而内部类有效的实现了“多重继承”

成员
成员内部类
静态内部类

局部
方法内部类
匿名内部类

依赖外部类对象的:成员内部类,方法内部类。匿名内部类

静态内部类不依赖外部类的对象,所以,我们项目中优先考虑静态内部类(不会产生内存泄露)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值