`
peonyzzdx
  • 浏览: 590604 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

外部类和内部类

 
阅读更多
内部类的共性

内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类。
(1)、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 OutClass$InterClass.class
(2)、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。
(3)、内部类声明成静态的,就不能随便的访问外部类的成员变量,仍然是只能访问外部类的静态成员变量。
(4)内部类不能定义静态变量。

因为内部类特殊,他被定向为是和成员变量,方法一样的外部类成员
他必须跟外部类实例相关联才能初始化,这是他的特点之一,为了这个其他东西都要让路
而静态成员是不需要实例就初始化的
如果一个非静态内部类有了静态成员,静态成员不依托于任何内部类实例,那结果也就是此内部类不需要外部类实例就初始化了变量,严重侵害了内部类的定向


成员内部类
成员内部类的优点:
⑴ 内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为PRIVATE,但是对于处于其内部的内部类还是可见的。)
⑵ 用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限
注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。
class Outer {
class Inner{}
}
编译上述代码会产生两个文件:Outer.class和Outer$Inner.class。



方法内部类(局部内部类)

顾名思义,把类放在方法内。
class Outer {
public void Dosomething(){
class Inner{
public void seeOuter(){
}
}
}
}

A、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。









局部内部类特点:1.方法内创建的类,不能加访问修饰符。
(2)、方法内部类对象不能使用该内部类所在方法的非final局部变量。
即局部内部类只能使用方法局部final变量
原因入下:
(1)设方法f被调用,从而在它的调用栈中生成了变量i,此时产生了一个局部内部类对象inner_object,它访问了该局部变量i .当方法f()运行结束后,局部变量i就已死亡了,不存在了.但:局部内部类对象inner_object还可能   一直存在(只能没有人再引用该对象时,它才会死亡),它不会随着方法f()运行结束死亡.这时:出现了一个"荒唐"结果:局部内部类对象inner_object要访问一个已不存在的局部变量i!
   (2)如何才能实现?当变量是final时,通过将final局部变量"复制"一份,复制品直接作为局部内部中的数据成员.这样:当局部内部类访问局部变量时,其实真正访问的是这个局部变量的"复制品"(即:这个复制品就代表了那个局部变量).因此:当运行栈中的真正的局部变量死亡时,局部内部类对象仍可以访问局部变量(其实访问的是"复制品"),给人的感觉:好像是局部变量的"生命期"延长了.


把类放在方法内
class Outer {
public void doSomething(){
class Inner{
public void seeOuter(){
}
}
}
}
值得注意的是:方法内创建的类,不能加访问修饰符。
(1)、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。

class Outer {
public void doSomething(){
final int a =10;
class Inner{
public void seeOuter(){
System.out.println(a);// 若把a去掉final,则会错。
}
}


匿名内部类(是局部内部类,存在方法和作用域内的)

顾名思义,没有名字的内部类。表面上看起来它们似乎有名字,实际那不是它们的名字。
在使用匿名内部类时,要记住以下几个原则:
·一个匿名类,它通过实例初始化实现构造,所以匿名类不可能有构造器
·匿名内部类不能定义任何静态成员、静态方法。
·匿名内部类不能是public,protected,private,static。
·只能创建匿名内部类的一个实例。
·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。



匿名类本身就是通过继承类或者接口来实现的。但是不能再显式的extends 或者implements了



1.怎样判断一个匿名类的存在啊?看不见名字,感觉只是父类new出一个对象而已,没有匿名类的名字。

先看段伪代码
abstract class Father(){
....
}
public class Test{
   Father f1 = new Father(){ .... }  //这里就是有个匿名内部类
}
一般来说,new 一个对象时小括号后应该是分号,也就是new出对象该语句就结束了。
但是出现匿名内部类就不一样,小括号后跟的是大括号,大括号中是该new 出对象的具体的实现方法。

因为我们知道,一个抽象类是不能直接new 的,必须先有实现类了我们才能new出它的实现类。
上面的伪代码就是表示new 的是Father的实现类,这个实现类是个匿名内部类。
其实拆分上面的匿名内部类可为
class SonOne extends Father{
  ...//这里的代码和上面匿名内部类,大括号中的代码是一样的
}
public class Test{
   Father f1 = new SonOne() ;
}

匿名内部类

注意,匿名内部类后面的分号不可缺少!

匿名内部类由于没有名字,所以它没有构造函数(但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实现的过程中使用 super 关键字调用相应的内容)。如果你想要初始化它的成员变量,有下面几种方法:
1. 如果是在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为 final 。

class Outer {
public void doSomething() {
final int a = 10;
class Inner extends MyTest implements interTest{
public void seeOuter() {
System.out.println(a);
}
}

new Outer(){
};


}

public static void main(String args[]){
new Outer(){
};
}
}


A、继承式的匿名内部类
public class Car {
public void drive(){
System.out.println("Driving a car!");
}
public static void main(String[] args) {
Car car = new Car(){
public void drive() {
System.out.println("Driving anther car!");
}
};
car.drive();
}
}
结果输出了:Driving another car! Car引用变量不是引用Car对象,而是Car匿名子类的对象。
B、接口式的匿名内部类。
interface Vehicle {
public void drive();
}
class Test{
public static void main(String[] args) {
Vehicle v = new Vehicle(){
public void drive(){
System.out.println("Driving a car!");
}
};
v.drive();
}
}
上面的代码很怪,好像是在实例化一个接口。事实并非如此,接口式的匿名内部类是实现了一个接口的匿名类。而且只能实现一个接口。
C、参数式的匿名内部类。
class Bar{
void doStuff(Foo f){}
}
interface Foo{
void foo();
}
class Test{
static void go(){
Bar b = new Bar();
b.doStuff(new Foo(){
public void foo(){
System.out.println("foofy");
}
});
}
}

静态嵌套类
静态内部类中可以定义静态或者非静态的成员。
从技术上讲,静态嵌套类不属于内部类。因为内部类与外部类共享一种特殊关系,更确切地说是对实例的共享关系。而静态嵌套类则没有上述关系。它只是位置在另一个类的内部,因此也被称为顶级嵌套类。
静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它。静态嵌套类仅能访问外部类的静态成员和方法。


class Outer{
static class Inner{}
}
class Test {
public static void main(String[] args){
Outer.Inner n = new Outer.Inner();
}
}

嵌套类可以作为接口的内部类。正常情况下,你不能在接口内部放置任何代码,但嵌套类可以作为接口的一部分,因为它是static 的。只是将嵌套类置于接口的命名空间内,这并不违反接口的规则。


public interface Test {

static class mm {

}

}


为什么需要内部类

为何要内部类?
    a、内部类提供了某种进入外围类的窗户。
    b、也是最吸引人的原因,每个内部类都能独立地继承一个接口,而无论外围类是否已经继承了某个接口。
  因此,内部类使多重继承的解决方案变得更加完整,内部类有效地实现了“多重继承”。

  在项目中,需要多重继承,如果是两个接口,那么好办,接口支持多重继承。
  如果是两个类呢?这时只有使用内部类了。



//内部类可以作为一个父类被继承
内部类被继承,由于内部类有一个指向外围类对象的秘密引用,所以在继承内部类的时候,该秘密引用必须被初始化。解决方法是
enclosingClassReference.super();语法,看一下代码:
   
class Outer{  
     class Inner {      
  }  
}
  
class AnoClass extends Outer.Inner{  
     AnoClass (Outer wi){  
             wi.super(); //这里是必须的,否则出错
    
  }
}





//成员内部类 实例化

public class OuterTest {

	public class InterTest {

		public InterTest(String m) {
			System.out.println(m);
		}
	}

	public static void main(String[] args) {
		OuterTest ot = new OuterTest();
      //创建某个内部类的对象方法一
		OuterTest.InterTest it = ot.new InterTest("88");
	}
}




public class OuterTest {
	public class InterTest {

		public InterTest(String m) {
			System.out.println(m);
		}
	}

	public InterTest Inter(String strs) {
		return new InterTest(strs);
	}

	public static void main(String[] args) {
		OuterTest ot = new OuterTest();
		// OuterTest.InterTest it = ot.new InterTest("88");
//创建某个内部类的对象方法二
		OuterTest.InterTest it = ot.Inter("88");
	}
}



public class OuterTest {
	private int i = 9;

	public int decrease(int m) {
		return (m -= 1);
	}

	public class InterTest {
		private int lable = 6;

		public InterTest(String m) {
			System.out.println(m);
		}

		public int increase() {
			// 内部类调用外部类的字段i
			return this.lable = ++i;
		}

		public int voke() {
			// 内部类调用外部类的方法decrease(int m)
			return decrease(lable);
		}
	}

	public static void main(String[] args) {
		OuterTest ot = new OuterTest();
		OuterTest.InterTest it = ot.new InterTest("88");
		System.out.println("内部类调用外部类的字段i:" + it.increase());
		System.out.println("内部类调用外部类的方法decrease():" + it.increase());
	}
}






//内部类实现接口
public interface Test {
	boolean start();

	int current();

	void end();
}


public class OuterTest {
	private int i = 9;

	public int decrease(int m) {
		return (m -= 1);
	}

	public class InterTest implements Test  {
		private int lable = 6;

		@Override
		public boolean start() {
			return true;
		}

		@Override
		public int current() {
			this.lable = 8;
			return 0;
		}

		@Override
		public void end() {
		}

	}

	public static void main(String[] args) {
		OuterTest ot = new OuterTest();
		OuterTest.InterTest it = ot.new InterTest();
		it.start();
		it.current();
		it.end();

		Test inter = ot.new InterTest();
		inter.start();
		inter.current();
		inter.end();

	}
}


//内部类可以继承类或实现接口

package ldd;

class Outer {
	public void doSomething() {
		final int a = 10;
		class Inner [color=red]extends MyTest implements interTest[/color]{
			public void seeOuter() {
				System.out.println(a);
			}
		}
	
		new Outer(){
		};
		
	}
	
	public static void main(String args[]){
		new Outer(){
		};
	}
}

0
12
分享到:
评论

相关推荐

    内部类和设计模式1

    根据定义的位置,内部类可以分为四种类型:成员内部类、局部内部类、静态内部类和匿名内部类。 1. **成员内部类** - 成员内部类就如同外部类的成员一样,与成员变量和成员方法处于同一级别。 - 声明:`public ...

    内部类详解,看了他就不用看其他资料了

    - 在外部类内部,创建成员内部类对象的方式与创建普通对象类似,使用`new`操作符调用构造方法。 - 在外部类外部,需要使用`<外部类类名>.<内部类类名>`的语法,通过外部类对象的引用调用`new`来创建内部类对象。 ...

    java(Day12)---内部类

    内部类主要有四种类型:成员内部类、静态内部类、局部内部类和匿名内部类。 1. 成员内部类: 成员内部类可以直接访问外部类的所有成员,包括实例变量和方法。它定义的位置是在类中,但不在任何方法之内。成员内部...

    java中的内部类总结

    - 当内部类和外部类有同名成员变量时,内部类的成员变量优先级更高,需要使用 `this` 指代内部类的成员,`OuterClass.this` 指代外部类的成员。 - 在实例方法中,局部变量可以遮蔽外部类和内部类的成员变量,需要...

    Android学习之内部类

    - 在外部类内部直接创建:`Inner inner = new Inner();` - 在外部类外部创建:`Outer outer = new Outer(); Inner inner = outer.new Inner();` #### 三、局部内部类 局部内部类是在方法或构造函数内部定义的类。...

    Java 深入理解嵌套类和内部类

    非静态嵌套类可以分为三种:在一个类中直接定义的内部类、在一个方法中定义的内部类和匿名内部类。匿名内部类是指没有名字的内部类,通常用于实现某个接口或继承某个类。 四、在外部类中定义内部类 在外部类中定义...

    Java内部类总结.pdf

    若内部类和外部类有同名成员,访问外部类成员时需使用`外部类名.this.外部成员名`的形式。 - **创建内部类对象**:必须通过外部类的实例来创建内部类对象,如`外部对象名.new 内部类构造方法()`。 ### 3. 部类与...

    Java的内部类讲解案例代码(成员内部类、局部内部类、匿名内部类、静态内部类、外部类访问四种内部类、其他类访问四种内部类...)

    - 不同类型的内部类(静态内部类、成员内部类、局部内部类和匿名内部类)的区别和用法 - 内部类的优缺点以及使用场景 这些目标将帮助你理解和掌握内部类的概念,并能够在适当的时候使用内部类来解决问题...

    Java内部类

    需要注意的是,如果外部类和内部类中有同名的成员变量,那么内部类可以通过 `OuterClass.this` 来区分它们: ```java class OuterClass { private int mMem = 10; public class InnerClass { private int mMem ...

    Java内部类和外部类的关系

    这个类对学习java很有帮助,这个类对学习java很有帮助,这个类对学习java很有帮助,这个类对学习java很有帮助,这个类对学习java很有帮助,这个类对学习java很有帮助,这个类对学习java很有帮助,这个类对学习java很...

    android 外部类作为事件监听器类

    然而,描述中提到的一个限制是,外部类形式的事件监听器不能自由地访问创建GUI界面的方法和组件。 在Android中,通常我们会在Activity或Fragment这样的UI组件内部定义匿名内部类来实现监听器,这样可以直接访问到UI...

    接口--内部类--多继承

    内部类分为四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。其中,成员内部类可以像普通成员一样在类的任何地方声明,而局部内部类只能在方法或代码块中定义。内部类的使用增强了代码的封装性,使得某些...

    15.java静态内部类(相当于外部类).zip

    15.java静态内部类(相当于外部类).zip15.java静态内部类(相当于外部类).zip15.java静态内部类(相当于外部类).zip15.java静态内部类(相当于外部类).zip15.java静态内部类(相当于外部类).zip15.java静态内部...

    内部类 匿名内部类 内部接口 对比说明

    这使得接口成为连接内部类和外部类的桥梁,帮助实现特定的交互逻辑。 总结一下,内部类、匿名内部类和内部接口在Java编程中提供了一种强大的工具,它们可以帮助我们更好地组织代码,实现封装和模块化。在Android...

    内部类分类及应用

    内部类可以分为四种:成员内部类、静态嵌套类、方法内部类和匿名内部类。每种内部类都有其特点和应用场景。 一、成员内部类 成员内部类是指定义在外部类中的内部类。它们可以访问外部类的所有成员变量和方法,无论...

    java中内部类与外部类的学习资料.docx

    理解并熟练掌握内部类和外部类的概念及用法对于编写更加灵活和高效的Java代码至关重要。它们可以在设计模式中扮演重要角色,如单例模式、策略模式等。同时,内部类也是Java事件处理机制的核心组成部分,如Swing中的...

    Java4Android 35_内部类和匿名内部类

    在Java编程语言中,内部类和匿名内部类是两种特殊类型的类,它们为代码的组织和功能实现提供了独特的灵活性。本教程"Java4Android 35_内部类和匿名内部类"深入探讨了这两个概念,旨在帮助开发者更好地理解和运用它们...

    java内部类总结(含概念和实例)

    内部类可为静态,可用 protected 和 private 修饰(而外部类只能使用 public 和缺省的包访问权限)。 Java 内部类的主要特点是: 1. 内部类可以访问外部类的所有成员,包括私有成员。 2. 内部类可以继承自某个类或...

    java 内部类使用(内部匿名类)

    1. **成员内部类**:成员内部类就像是外部类的一个普通成员,可以是静态或非静态的。非静态内部类拥有对外部类的引用,可以直接访问外部类的所有成员,包括私有成员。而静态内部类不持有对外部类的引用,因此只能...

    Java语法总结 - 内部类

    内部类可以分为四种:成员内部类、静态嵌套类、方法内部类和匿名内部类。 成员内部类 成员内部类是定义在外部类的成员变量中的一种内部类。它可以访问外部类的所有成员变量和方法,包括私有的变量和方法。成员内部...

Global site tag (gtag.js) - Google Analytics