昨天看了THANKING JAVA中的内部类,结合自己的经历,在这里做个小节,算是读后感吧
public class Parent {
protected String p ="p"; //这里的P不能为private,必须为protected或public,不然c无法调用 至于为什么,自己想想吧。
protected boolean p() {
return true;
}
}
public class A extends Parent {
private String a = "a";
private boolean a() {
return true;
}
public class B extends A {
private String b = "b";
private boolean b() {
return true;
}
public void vistorAllParentClass(){
System.out.println("b:"+b);
System.out.println("a:"+a);
System.out.println("p:"+p);
System.out.println("b():"+b());
System.out.println("a():"+a());
System.out.println("p():"+p());
}
}
}
public class Test {
public static void main(String[] a){
A.B b = new A().new B(); //注意 非静态内部类必须依赖于外围类的对象才能创建,所以有以上语法。
b.vistorAllParentClass();
}
}
可以看出上述代码 实现了 b这个内部类能同时访问父类A,以及A的父类Parent属性极其方法,
这就间接的实现C++中的多重继承特性
同时比继承更进一步,能访问父类的PRIVATE属性及其方法!!!!
仔细看上面的代码,会发现
A.B b = new A().new B(); 这种编码方式有股坏味道。
因为如果没有研究过A类的代码,将无法了解A的继承体系,从而无法得知B,
同时将作为内部类B设置为PUBLIC暴露出A类的大量内部细节,也不是什么好的设计。
如何解决这种粗糙的编码方式呢?
这就涉及到接口了,定义一个 接口:
public interface Vistor{
void vistorAllParentInfo();
}
然后 将A的代码改成:
public class A extends Parent {
private String a = "a";
private boolean a() {
return true;
}
private class B extends A implements Vistor{
private String b = "b";
private boolean b() {
return true;
}
public void vistorAllParentInfo(){
System.out.println("b:"+b);
System.out.println("a:"+a);
System.out.println("p:"+p);
System.out.println("b():"+b());
System.out.println("a():"+a());
System.out.println("p():"+p());
}
}
public Vistor getVistor(){
return new A().new B();
}
}
然后 将Test的代码改成:
public class Test {
public static void main(String[] args){
A a = new A();
Vistor vistor = a.getVistor();
vistor.vistorAllParentInfo();
}
}
此时就能通过 Vistor vistor = a.getVistor();
将实现了多重继承,携带了所有父类内部细节的B类以接口形式暴露出部分行为。
这种方式带来的好处出来便于使用B类,同时也体现了面向对象中的封装性,使用安全的接口操作对象的属性和行为,而无需知道实际对象的内部细节。
注意看 A中B类的访问权限是private,而Vistor是public,并且Test能捕获转型后的B类,即B的接口方法作为PUBLIC抛到了外围类。
这一点将"接口行为与具体类的实现无关"这一继承特性 体现的淋漓尽致!!!
让我们再来看看内部类是如何化解继承中"is a"的困惑的。
在编程时,我们有时会遇到这种困境:
//行为
public interface Behavior{
void addItem(String data);
void delItem(int i);
};
//数据
public class DataSource{
private List dataList = new ArrayList();
}
public class Deal{
public static void main(String[] a){
//下面我们要使用Behavior的接口来操作dataSource。 该如何办呢?
}
}
上面Deal提出的疑问我们该如何解决呢?Behavior并没有提供方法可以获取一个dataSource的应用。
简单考虑有两种方法能解决上述问题:
1 定义一个Behavior具体类BehaviorImpl 并加入方法setDataSource(DataSource data);然后操作。
2 将DataSource继承Behavior,然后重载接口行为。
来看看两种方式缺点:
首先方法1
将导致创建新类,同时Behavior的实现必须和Deal的main方法实现耦合在一起,并且暴露了Behavior与DataSource关联的细节。
因为只有在Deal的main中使用behaviorImpl.setDataSource(data);的形式来使方法1成立。
然后是方法2
DataSource继承Behavior 将导致"is a"的困惑出现:DataSource究竟是一个数据源对象还是一个行为对象呢?
这模糊DataSource对象的语义。
如果使用内部类就能解决上述问题了~~~~~~
改造下DataSource
public class DataSource{
private List dataList = new ArrayList();
public Behavior getBehavior(){
return new Behavior(){
public void addItem(String data){
dataList.add(data);
}
public void delItem(int i){
dataList.remove(i);
}
};
}
}
public class Deal{
public static void main(String[] a){
DataSource d = new DataSource();
Behavior b = d.getBehavior();
b.addItem("12121";
b.delItem(0);
}
}
这样就将具体DataSource对象的具体行为封装到DataSource中了,避免了添加新类,同时也封装了DataSource 与 Behavior的关联实现。
并且达到对象语义上的清晰-------"DataSource对象是一个数据源,并带有一个在其数据上进行操作的具体行为对象Behavior"
至于内部类对回调的支持,主要也是通过接口和匿名内部类实现,方式与上面的差不多,不说也罢。
分享到:
相关推荐
对于想要深入了解Java内部机制、提升编程技能或从事软件开发工具链研究的专业人士来说,《现代编译器的Java实现(第二版)》是一本不可多得的参考书。通过学习这本书,不仅可以掌握编译器设计的核心原理,还能加深对...
Java 12是Java开发平台的一个重要版本,它引入了多个新特性,改进了性能,并对API进行了扩展。本文将深入探讨Java 12的JDK源码和API,帮助开发者更好地理解和利用这个版本。 首先,Java JDK(Java Development Kit...
6. **第七章例题**:可能涉及面向对象的高级主题,如接口、内部类、抽象类以及集合框架的初步接触,如ArrayList和LinkedList。 7. **第九章例题**:可能深入到IO流(Input/Output Stream),包括文件操作、字节流、...
- 内部类的分类:成员内部类、局部内部类等 - 内部类的访问权限 - **线程池专题** - 线程池的原理与优势 - Executor框架介绍 - 创建线程池的方式 - **设计模式初步** - 设计模式的定义与分类 - 常见设计模式...
### Java版WorldWind源代码解析知识点 ...每个类和方法都有其独特的功能和应用场景,通过对它们的细致研究,不仅可以深入了解WorldWind的内部运作机制,还可以在此基础上进行优化和扩展,以满足更加复杂的应用需求。
【Java 销售管理系统】是一个基于Java技术和SQL Server 2000数据库的管理软件,旨在实现销售管理的系统化、规范...经过全面评估,确认该系统具备开发和实施的可行性,对提升公司的内部管理效率和经济效益具有积极意义。
Krakatau不仅提供反编译功能,还能分析和重建类文件结构,对于深入研究Java字节码非常有用。 6. **JAD**:Java Archive Decompiler(JAD)是一个早期的Java反编译工具,它能够将.class文件反编译为类似源代码的文本...
以上是《Thinking in Java》第四版的主要知识点概览,本书不仅适合Java初学者入门学习,也适合有经验的开发者深入研究和参考。通过系统地学习本书内容,可以帮助读者全面掌握Java语言的各个方面,并提升解决实际问题...
5. **开题报告**:开题报告通常是在项目开始阶段撰写,用于阐述项目的目标、研究方法、预期成果等内容,它是项目实施的初步规划,为后续的开发工作提供了方向。 在【压缩包子文件的文件名称列表】中提到的"JAVA基于...
【Java版OA代码】是基于Java编程语言实现的办公自动化(Office Automation)系统的核心源代码。...深入研究这些文件将有助于我们全面了解Java版OA系统的架构和实现细节,这对于开发、维护或扩展系统都是非常有价值的。
总的来说,这个基于Java的中文自动分词项目为开发者和研究者提供了一个实践和学习自然语言处理技术的平台,无论你是想了解分词算法的内部工作原理,还是需要一个现成的分词工具,都能从中受益。通过深入研究源码,...
通过对现有仓库管理方式的研究,发现传统管理方式存在的问题,如数据不准确、工作效率低下等。 **2.2 现行系统详细调查** 深入调研现有系统的具体运作模式、存在的瓶颈及改进空间。 **2.3 系统需求分析** 根据前期...
DD.exe作为一个轻量级的工具,可能不具备高级反编译器的一些特性,如对Java字节码的深度分析、重构优化或对混淆代码的处理。但它胜在简便快捷,适合快速查看和理解简单的字节码结构,对于开发者进行日常的调试或学习...
企业内部管理系统是组织内部进行日常运营、管理及信息交流的重要工具。这个系统是基于JSP(JavaServer Pages)和Servlet技术构建的,采用MySQL作为后端数据库,设计上遵循了三层架构模式,非常适合初级开发者学习和...
通过深入研究这些文件,开发者可以了解系统内部的工作原理,进行二次开发或调试。例如,ldl1可能代表“登录与数据层”(Login and Data Layer),包含用户登录逻辑和数据存取的代码;而实验1可能是系统的初步实现或...
1. **第一章:万物皆对象** - 介绍了面向对象编程的基本理念,包括类、对象、封装、继承和多态等概念,让读者对OOP有初步认识。 2. **第二章:程序控制** - 讲解了条件语句(if-else, switch)和循环结构(for, ...
通过jdgui,开发者可以快速浏览和理解Java类文件,它提供了源代码视图,便于分析应用程序的逻辑。虽然不支持编辑或保存源代码,但作为初步分析和理解代码结构的工具,jdgui非常实用。 2. **apktool**:这是Android...
- 中级:能够主动识别低效或冗余环节,提出初步解决方案。 - 高级:能够从用户体验角度出发,优化前端交互效果。 - 资深/专家:具备全局视野,能够提出系统级别的改进措施。 #### 五、技术吻合度 - **考核点**...
无论是对Spring框架有初步了解的初学者,还是寻求提升技术深度的资深开发者,都能从中受益匪浅。通过仔细研读这些资料,开发者可以提升自己的Java和Spring技术水平,更好地应对企业级开发中的各种挑战。