黑马程序员——Java基础——内部类

原创 2015年07月08日 08:53:22
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------


什么是内部类,简单来说就是一个外部类的内部又定义了一个类,那为什么需要内部类呢?

因为内部类可以直接访问外部类中的成员,包括私有。用现实的例子描述就是一个人是由大脑、肢体、器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏,它也有自己的属性和行为(血液、跳动),心脏可以直接访问身体的血液,而不是通过医生来抽血,这时不能用属性或者方法表示一个心脏,而是用一个类

内部类可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this

外部类要访问内部类,必须建立内部类对象

内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。

1.成员内部类

就是将内部类定义在外部类的成员位置,而且非私有,可以在外部其他类直接建立内部类对象。格式:

外部类名.内部类名  变量名 = 外部类对象.内部类对象;
 Outer.Inner in = new Outer().new Inner();

开头的Outer是为了标明需要生成的内部类对象在哪个外部类当中。必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量。

//定义外部类
class Outer
{
	//定义内部类
	class Inner
	{
		void show()
		{
			System.out.println("内部类运行...");
		}
	}
}


public class InnerClassDemo {

	public static void main(String[] args) {
		
		//在外部其他类建立内部类对象
		Outer.Inner in = new Outer().new Inner();
		in.show();
	}

}


当内部类在成员位置上,就可以被成员修饰符所修饰。
private:将内部类在外部类中进行封装。如同是,我的心脏只能由我的身体控制,其他人无法直接访问它

static:内部类就具备static的特性。当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。

在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();

在外部其他类中,如何直接访问static内部类的静态成员呢?
Outer.Inner.function();

 注意:当内部类中定义了静态成员,该内部类必须是static的。
       当外部类中的静态方法访问内部类时,内部类也必须是static的。

//定义外部类
class Outer
{
	//内部类被static修饰后,只能直接访问外部类中的static成员
	private static int num = 2;
	static class Inner
	{
		static void show()
		{
			System.out.println("内部类运行..."+num);
		}
	}
}




public class InnerClassDemo {

	public static void main(String[] args) {
		Outer.Inner.show();
	}

}


2.局部内部类

内部类定义在外部类中的某个方法中,创建了这个类型的对象时,且仅使用了一次,那么可在这个方法中定义局部类。

不可以被成员修饰符修饰,如public、private、static等修饰符修饰。它的作用域被限定在了声明这个局部类的代码块中

可以直接访问外部类中的成员,因为还持有外部类中的引用。

但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。为什么呢?

因为局部内部类对象和局部变量的生命周期不同,内部类需要复制局部变量为内部类的一个成员变量,为了保证局部变量和该副本的值的一致性,所以要将修饰符设为final。

//定义外部类
class Outer
{
	//局部内部类访问局部变量必须用final修饰
	void show(final int num)
	{	
		//内部类定义在外部类方法内
		class Inner
		{
			void show()
			{
				System.out.println("内部类运行..."+num);
			}
		}
		//访问语句必须在定义类局部内部类之后
		new Inner().show();
	}
}


public class InnerClassDemo {

	public static void main(String[] args) {
		
		Outer out = new Outer();
		out.show(3);//内部类运行...3
		out.show(4);//内部类运行...4

	}

}


3.匿名内部类

没有名字的内部类。就是内部类的简化形式。一般只用一次就可以用这种形式简化书写。

定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。
匿名内部类的格式:  new 父类或者接口(){定义子类的内容}
其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。 可以理解为带内容的对象。
匿名内部类中定义的方法最好不要超过3个。

public class InnerClassDemo {

	public static void main(String[] args) {
		
		//编译通过,运行
		new Object(){
			void show(){
				System.out.println("show run");				
			}
		}.show();
		
		//编译失败,因为匿名内部类是一个子类对象,当用Object的obj引用指向时,
		//就被提升为了Object类型,而编译时检查Object类中是否有show方法

		Object obj = new Object(){
			void show(){
				System.out.println("show run");
			}
		};
		obj.show();
	}

}

从上面这个例子可以看出,匿名内部类就是参照多态的表达形式,用父类引用接收一个子类对象,编译运行参照多态的规则。

4.匿名内部类的扩展

可以通过匿名内部类的方式实现多重继承

//创建一个使用继承的类
abstract class Normal
{
	abstract void methodNomal();
}
//创建一个使用匿名内部类的类
abstract class Outer
{
	abstract void methodOuter();
}

//创建实现多重继承的类
class Multi extends Normal
{

	//复写父类的方法
	@Override
	void methodNomal() {
		System.out.println("normal method ...");
		
	}
	
	//创建返回匿名内部类对象的方法
	public Outer getOuter(){
		
		return new Outer(){

			@Override
			void methodOuter() {
				
				System.out.println("Outer method...");
			}
			
		};
	}
}

public class InnerClassDemo {

	public static void main(String[] args) {
		 
		//实现一个类的多重继承,调用方法
		Multi m = new Multi();
		m.methodNomal();
		m.getOuter().methodOuter();
	}
}


5.继承内部类

在学习了内部类的基础知识后,产生了一个疑问,既然内部类也是一个类,那它能不能被继承呢

//定义外部类
class Outer
{
	//定义内部类
	class Inner
	{
		Inner()
		{
			System.out.println("内部类运行...");
		}
	}
}
//继承时需要指定外部类名称
class ExtendsClass extends Outer.Inner
{
	//ExtendsClass();无法通过编译
	//构造函数需要传递外部类对象
	ExtendsClass(Outer out)
	{
		//调用内部类的构造函数
		out.super();
	}
}

public class InnerClassDemo {

	public static void main(String[] args) {
		 
		//创建外部类对象,并传入继承类的构造函数,完成初始化
		Outer out = new Outer();
		ExtendsClass ex = new ExtendsClass(out);
	}
}


上面就是继承内部类的代码,为什么要这样写?

继承内部类后,需要调用内部类的默认构造函数,但是加载内部类必须先加载外部类,所以要给继承类的构造函数传入外部类的对象,然后通过外部类.super()来调用内部类的默认构造函数完成初始化。









版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

黑马程序员——java基础--多态、内部类、异常、包

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流----- 一、多态 1、概述   什么是多态?某一事物在不同时刻表现出来的不同状态。 如:猫可以是猫的类型。...

黑马程序员——java基础(面向对象)抽象、接口、内部类

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 第五章:面向对象(抽象、接口、内部类)   本章概述: 第一部分:抽象  抽象描述 抽...

黑马程序员——Java基础--多态、内部类、异常

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 多态、内部类、异常 一、多态 1、多态:可以理解为事物存在的多种体现形态。 例:动物...

黑马程序员——java基础 内部类

一、 内部类 内部类: 在一个类中的另一个类 将一个类,定义在了另一个类中 嵌套类class Outer { class Inner { } }对于...

黑马程序员——Java 基础:匿名内部类

一、概述 使用匿名内部类是在编写 Java 程序时经常会使用的一种简化代码的方式,常用于创建线程并重写 run 方法。二、什么匿名内部类 (1)使用有名称的内部类时的代码// 创建一个具有内部类的...

黑马程序员——Java基础---多态、内部类、异常、包

第一讲     多态         多态可以理解为事物存在的多种体现形态。         例:动物中猫,...

黑马程序员 ——Java基础之内部类、异常、包

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 内部类   在类内部可定义成员变量与方法,有趣的是,在类内部也可以定义另一个类。如果在类 ...

黑马程序员——java基础----面向对象(三)内部类

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 内部类

java基础--抽象类、接口、多态、内部类、异常、包

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 1、抽象类(abstract)    特点: 1)抽象方法一定在抽象类中; 2)抽象方法和...

黑马程序员——Java基础——内部类

内部类:就是在类里面定义的类。 1、可以直接访问外部类的成员,包括私有的。 2、外部类要访问内部在类,要建立内部类对象。
  • twa42
  • twa42
  • 2015-06-09 23:20
  • 117
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)