`

java编程思想笔记(七)内部类

阅读更多

1.内部类的定义:

将一个类的定义放到另一个类内部中,即为内部类。内部类可调用外围类的成员变量和方法,

像这种直接在外围类中定义的内部类,叫成员内部类,这种内部类可使用到外围类全部的成员变量和方法.

 

内部类也能保证抽象类或具体类实现多重继承的功能。(如用多个不同内部类去继承多个不同具体类)

 

内部类就像是一个怀孕的妈妈肚子里的孩子,孩子可以吸收到母亲的养分,又能有自己成员信息.

 

2.在外部类的非静态方法中创建内部类的对象语法:

外部类类名.内部类类名 对象名 = 外部类对象.new 内部类类名();

 

3.this. 或  new

内部类使用 外围类.this,可引用外围类对象,外围类可以通过new得到内部类对象,外围类之外是做不到的.

 

public class Outter{  
    void f(){  
System.out.println(“Outter f() method”);  
}  
    class Inner{  
    public Outter outer(){  
        return Outter.this;  
}  
}  
    public Inner inner(){  
        return new Inner();  
}  
} 

 

 

4.内部类实现接口后的向上转型.

 

 

 

interface Contents {
	int value();
}  

public interface Destination {
	String readLabel();
}  

class outer{
	private class PContents implements Contents {
		private int i = 11;

		public int value() {
			System.out.println("PContents value");
			return i;
		}
	}

	protected class PDestination implements Destination {
		private String label;

		private PDestination(String whereTo) {
			label = whereTo;
		}

		public String readLabel() {
			System.out.println(label);
			return label;
		}
	}

	public Destination destination(String s) {
		return new PDestination(s);
	}

	public Contents contents() {
		return new PContents();
	}
}
public class TestOuter {
	public static void main(String[] args) {
		Outer p = new Outer();
                Contents c = p.contents();
		Destination d = p.destination("Tasmania");
		c.value();
		d.readLabel();
		// Illegal -- can't access private class:
		// ! Outer.PContents pc = p.new PContents();
	}
} // /:~

 

5.在方法和作用域内的内部类

 

    定义在方法里的局部内部类:

 

public class Parcel5 {
	public Destination destination(String s) {
		//定义在方法里,为局部内部类
		class PDestination implements Destination {
			private String label;

			private PDestination(String whereTo) {
				label = whereTo;
			}

			public String readLabel() {
				return label;
			}
		}
		return new PDestination(s);
	}

	public static void main(String[] args) {
		Parcel5 p = new Parcel5();
		Destination d = p.destination("Tasmania");
	}
} // /:~

 

 

作用域里的内部类

 

public class Parcel6 {
	private void internalTracking(boolean b) {

		if (b) {
			// 定义在if作用域内的内部类
			class TrackingSlip {
				private String id;

				TrackingSlip(String s) {
					id = s;
				}

				String getSlip() {
					return id;
				}
			}
			TrackingSlip ts = new TrackingSlip("slip");
			String s = ts.getSlip();

		}
		// 已经在作用域外部,内部类不能用于此:
		// ! TrackingSlip ts = new TrackingSlip("x");
	}

	public void track() {
		internalTracking(true);
	}

	public static void main(String[] args) {
		Parcel6 p = new Parcel6();
		p.track();
	}
} // /:~

 

 

6。匿名内部类

 

public class Parcel7 {
	public interface Contents {
		int value();
	} // /:~

	abstract class hhm {
		public int i = 5;

		public void ttt() {
		};
	}

	public Contents contents() {
		return new Contents() { // 这里直接new了Contents类,前提是要有个Contents名字的接口或类
			private int i = 11;

			public int value() {
				return i;
			}
		}; // *这里要分号
	}

	public hhm gethhm() {
		return new hhm() {

		};
	}

	public static void main(String[] args) {
		Parcel7 p = new Parcel7();
		Contents c = p.contents();
	}
} // /:~

 

 

 

如果匿名内部类的基类有个有参构造器,并且没有无参构造器.

那就直接参数传给匿名内部类,用super获取值.

 

public class Parcel8 {
	class Wrapping {
		private int i;

		public Wrapping(int x) {
			i = x;
		}

		public int value() {
			return i;
		}
	} // /:~

	public Wrapping wrapping(int x) {
		// Base constructor call:
		return new Wrapping(x) { // Pass constructor argument.
			public int value() {
				System.out.println(super.value());
				return super.value() * 47;
			}
		}; // Semicolon required
	}

	public static void main(String[] args) {
		Parcel8 p = new Parcel8();
		Wrapping w = p.wrapping(10);
		w.value();
	}
} // output : 10 /:~

 

为匿名内部类创建一个初始化构造器的效果:

 

abstract class Base {
	public Base(int i) {
		print("Base constructor, i = " + i);
	}

	public abstract void f();
}

public class AnonymousConstructor {
	public static Base getBase(int i) {
		return new Base(i) {
			{
				print("Inside instance initializer");
			}

			public void f() {
				print("In anonymous f()");
			}
		};
	}

	public static void main(String[] args) {
		Base base = getBase(47);
		base.f();
	}
} /*
 * Output: Base constructor, i = 47 Inside instance initializer In anonymous f()
 */// :~

 上面的方法参数i不需要加final修饰,因为i是传给了构造器

 若内部类想直接使用方法上的参数,那就用final修饰方法参数.

 

7.静态内部类

定义:内部类前面加static修饰即为静态内部类,也叫嵌套类。

1)静态内部类不需要外围类,即可创建静态内部类对象。

 2)不能从静态内部类对象中访问外围类的非静态内部类对象

 

public class Parcel11 {
	private int q = 5555;

	private static class ParcelContents implements Contents {
		private int i = 11;

		public int value() {
			// ! q++; //静态内部类中想调用外围类的参数q就必须用static修饰才能q++
			return i;
		}
	}

	static class ParcelDestination implements Destination {
		private String label;

		private ParcelDestination(String whereTo) {
			label = whereTo;
		}

		public String readLabel() {
			return label;
		}

		// Nested classes can contain other static elements:
		public static void f() {
		}

		static int x = 10;

		static class AnotherLevel {
			public static void f() {
				ParcelDestination.f();
			}

			static int x = 10;
		}
	}

	public static Destination destination(String s) {
		// 静态内部类不需通过外围类即可创建内部类
		return new ParcelDestination(s);
	}

	public static Contents contents() {
		return new ParcelContents();
	}

	public static void main(String[] args) {
		Contents c = contents();
		Destination d = destination("Tasmania");

	}
} // /:~
 

 

 8.闭包与回调

java中可以通过内部类实现闭包与回调

参考:

http://blog.csdn.net/yaerfeng/article/details/7326956

 

interface Incrementable {
	void increment();
}

// Very simple to just implement the interface:
class Callee1 implements Incrementable {
	private int i = 0;

	public void increment() {
		i++;
		System.out.println("Callee1 :" + i);
	}
}

class MyIncrement {
	public void increment() {
		print("Other operation");
	}

	static void f(MyIncrement mi) {
		mi.increment();
	}
}

// If your class must implement increment() in
// some other way, you must use an inner class:
class Callee2 extends MyIncrement {
	private int i = 0;

	public void increment() {
		super.increment();
		i++;
		System.out.println("Callee2 :" + i);
	}

	private class Closure implements Incrementable {
		public void increment() {
			// Specify outer-class method, otherwise
			// you'd get an infinite recursion:
			Callee2.this.increment();
		}
	}

	Incrementable getCallbackReference() {
		return new Closure();
	}
}

class Caller {
	private Incrementable callbackReference;

	Caller(Incrementable cbh) {
		callbackReference = cbh;
	}

	void go() {
		callbackReference.increment();
	}
}

public class Callbacks {
	public static void main(String[] args) {
		Callee1 c1 = new Callee1();
		Callee2 c2 = new Callee2();
		MyIncrement.f(c2);
		Caller caller1 = new Caller(c1);
		Caller caller2 = new Caller(c2.getCallbackReference());
		caller1.go();
		caller1.go();
		caller2.go();
		caller1.go();
		caller2.go();
	}
} /*
 * Output: Other operation 1 1 2 Other operation 2 Other operation 3
 */// :~
 

 

9.内部类的继承

   新类若想继承其它类中的内部类,必须先初始化其它类的构造器才用的到其中的内部类.

 

class WithInner {
	class Inner {
		
	}
}

public class InheritInner extends WithInner.Inner {
	// ! InheritInner() {} // 不能编译
	InheritInner(WithInner wi) {
		wi.super();
	}

	public static void main(String[] args) {
		WithInner wi = new WithInner();
		InheritInner ii = new InheritInner(wi);
	}
} // /:~

 

总结:

在代码块里创建内部类是使用局部内部类还是匿名内部类?

若需要一个已命名的构造器,或者需要重载构造器,或你需要更多内部类完成功能,就使用局部内部类.

若只需一个内部类作实例初始化,就用匿名内部类.

 

 

 

 

分享到:
评论

相关推荐

    java编程思想读书笔记

    ### Java编程思想读书笔记 #### 一、Java与C++的区别及内存管理 在学习Java的过程中,我们常常会拿它与C++进行比较。这两门语言虽然有着相似之处,但也有许多不同点。 1. **内存管理:** - C++提供了更为底层的...

    Java编程思想-笔记.docx

    Java编程思想笔记 本笔记涵盖了Java编程思想的多个方面,包括访问权限控制、封装、继承、多态、接口、内部类、持有对象等。 访问权限控制 访问权限控制是为了把变动的事物与保持不变的事物区分开来。Java中有四种...

    java编程思想笔记

    《Java编程思想笔记》是基于 Bruce Eckel 的经典著作 "Thinking in Java" 所做的学习总结,这本书深入浅出地介绍了Java语言的核心概念和技术。在本文中,我们将围绕Java编程的一些关键知识点进行深入探讨,包括但不...

    Java编程思想笔记(全)

    ### Java编程思想笔记知识点概述 #### 第 1 章 对象导论 在这一章节中,主要介绍了Java中的基本概念——对象。对象是面向对象编程的核心,它封装了数据和行为。本章首先解释了对象的概念,接着讨论了如何创建对象...

    Java编程思想重点笔记(Java开发必看)

    Java 编程思想是每一位Java开发者都需要深入了解的重要领域。这篇笔记涵盖了多个关键知识点,包括多态性、final方法、静态方法、构造函数以及构造过程中的多态行为。 首先,Java中的多态性是面向对象编程的核心特性...

    Java编程思想学习笔记

    在讨论Java编程思想学习笔记时,首先需要了解的是Java语言的平台无关性,而这一特性正是通过Java虚拟机(JVM)得以实现的。JVM作为Java程序设计的关键组成部分,对于Java开发人员来说是必须掌握的基础知识。在该学习...

    Java编程思想重点笔记(Java开发必看).pdf

    以上只是Java编程思想笔记中的冰山一角,深入学习还包括网络编程、数据库连接、JVM内存模型、垃圾回收机制、并发编程高级话题、Spring框架等内容。这些知识点构成了Java开发者必备的基础知识体系,通过不断学习和...

    达内JAVA培训综合笔记

    面向对象是Java编程的核心思想,笔记中对类、对象、包、方法及其调用、引用、访问控制、构造器、继承、接口等概念都进行了深入讲解。特别是继承和多态的概念,是理解Java面向对象程序设计的关键。此外,还涵盖了抽象...

    JAVA经典教材笔记

    - Java作为一种广泛使用的编程语言,其学习路径包括掌握基本语法、理解面向对象编程思想、熟悉标准库使用等。 - **JAVA发展概述** - Java的发展历程:从1995年由Sun Microsystems公司发布以来,Java经历了多次重大...

    JAVA学习笔记

    JAVA学习笔记是一个全面涵盖JAVA编程基础到进阶的资源集合,特别适合初学者掌握JAVA语言和项目开发技术。笔记内容包括了几个核心领域,如编程思想、多线程设计模式、网络编程,以及JAVA的新输入/输出(NIO)系统。 ...

    java私塾学习笔记整理

    ### Java私塾学习笔记整理 #### 第一章:Java入门 ...以上内容涵盖了Java基础知识的重要方面,从语言基础到高级特性,以及常见的开发技术和工具,帮助读者全面了解Java编程的基础知识和技术要点。

    中文版Thinking in Java 4th编程思想(笔记)

    《中文版Thinking in Java 4th编程思想》是学习Java编程的重要参考资料,它深入浅出地介绍了面向对象编程的核心概念。下面将详细解读其中的主要知识点。 1. **对象导论** - **万物皆对象**:Java编程的核心是对象...

    瑜琅java学习笔记

    ### 瑜琅Java学习笔记概览 瑜琅的Java学习笔记涵盖了Java的基础概念与核心特性,从起源到高级特性均有涉及。以下是对该学习笔记各部分的深入解析: ...希望这份笔记能够帮助更多的人更好地理解和掌握Java编程。

    java实战经典学习笔记

    通过这些知识点的学习,读者能够掌握Java的基础语法和面向对象编程的核心思想,并能够运用到实际的软件开发中去。此外,通过对各种高级特性和常用类库的深入理解,可以提高开发效率和代码质量。

    JAVA笔记达内培训内部笔记

    - **面向过程**:这是一种传统的编程思想,程序是由一系列的过程或步骤组成的,每个步骤通常通过函数来实现。这种思想强调的是如何实现算法,关注的是算法的流程。 - **面向对象**:面向对象是一种更现代化的编程...

Global site tag (gtag.js) - Google Analytics