【一】
一点大概的认识
a.记住他们都不可以new对象
在匿名内部类中,可以new 接口和抽象类!
b.接口不可以实现方法,
抽象类可以,
而且大部分的接口方法实现,会用抽象类来实现。
接口是一个抽象类的变体,主要是给外部提供属性和方法,不关注具体实现。用于提供业务比较好
c.
如果你的类方法没有任何实现,就用接口,有部分实现或者不想实例化该类,就用抽象类。
【二】
关于追溯父类构造方法的问题
a.
调用子类构造方法都会调用它的直接父类的构造方法
我觉得可以认为new才会返回一个实例的引用,而抽象类是不能new的(这个是规定,没理由)
调用子类构造方法是调用了它的抽象父类的构造方法
但构造方法是用来做初始化工作的,它并不会返回实例
b.
1、子类在创建实例后,类初始化方法会调用父类的初始化方法(除了java.lang.Object类,因为java.lang.Object类没有父类),而这种调用会逐级追述,直到java.lang.Object的初始化方法。
这个地方我说的是初始化方法,而不是构造方法,因为构造方法是相对于java源程序而言,而编译后的class文件是初始化方法即" <init>"方法(红色部分为方法名),初始化方法是由java源程序的三个部分组成的,一个部分是成员字段后的直接的初始化语句,例如private int i=0;private Date date=new Date();等等,第二个部分是由初始化块组成,例如:
Java codepublic class Test{
private int i=0;//初始化第一部分
//以下大括号内为初始化第二部分
{
this.i=4;
\\do something......
}
}
第三个部分就是java源代码中的构造方法中的代码,java源代码中有几个构造方法,那么class文件中就有几个初始化方法,编译器会把第一部分与第二部分分别复制到每个初始化方法的前端,然后把初始化方法对应参数的构造方法的代码复制到相应初始化方法中(这里说的复制其实应该说是编译,不过为了让你更好理解所以如此说).
那么说初始化方法如何追述其父类的,这也关系到初始化方法的结构,初始化方法的执行顺序以及结构就如上所说,但是每个初始化方法的第一个执行指令就是调用另外一个初始化方法,这个初始化方法可能是自身类某个初始化方法,例如你的构造函数中第一句有类似this(...)这种语句,那么初始化方法就会调用自身类的指定构造方法;如果你的构造方法中没有指定构造方法调用,那么初始化方法会默认调用父类
无参数初始化方法,如果你的子类第一句为super(....),那么初始化方法会调用父类指定初始化方法。这种调用过程会递归进行调用,直到这个类是java.lang.Object类。
调用初始化方法并不代表会生成对象,你的java代码中出现new关键字加上构造方法的调用,只会生成一个对象,其父类对象不会生成,所以调用父类为抽象类的构造方法完全是合理的。而且初始化方法对于虚拟机来说只是一个名称叫做" <init>"的普通方法,区别只是生成对象以后调用而已(sun 的jdk私有包中有绕过构造方法生成对象的方式,可以证明之上说法,具体如何我这里不陈述)。
然后回答你的第二个问题,抽象类中的构造方法其实是用来给继承的子类来用的,因为构造方法相当于初始化方法,当子类调用构造方法时必须调用父类构造方法,所以你可以在子类产生对象时抽象类中按需求初始化抽象类中的字段以及执行一些初始化代码。其实并不是一定要生成某个类的实例才调用构造方法,子类也需要调用父类构造方法。而生成实例也并不一定会调用构造方法,在某些特殊实现中或者特殊情况下,生成实例不会调用构造方法。而调用了构造方法也不一定就生成了一个实例,但是那一定是一个实例调用的,就像一个普通的实例方法一样。
c.
abstract class Person{
private String name;
public Person(String n){
name=n;
}
public String getName() {
return name;
}
public abstract String getInformation();
}
class Employee extends Person{
private double salary;
public Employee(String n,double s) {
super(n);
salary=s;
}
public double getSalary() {
return salary;
}
@Override
public String getInformation() {
return "级别:员工、工资:"+getSalary();
}
}
public class MainTest{
public static void main(String[] args){
Person p=new Employee();
}
}
抽象类不能被实例化是说Person p=new Person();这样是错误的;但是Person p=new Employee(); 是可以的,创建子类的实例,父类的引用指向它
在上述主程序中,new Employee后,它会初始化对象,初始化顺序为:
父类静态块初始化---->子类静态块初始化---->父类非静态块初始化---->父类构造方法---->子类非静态块初始化---->子类构造方法。(先静后动,先父后子)
这个主程序会先初始化person类的非静态属性和构造函数再初始化employees类的非静态属性和构造函数
这就是你第一个问题的当子类的父类为抽象类时,构造方法如何追溯?而抽象类作为父类也会创建实例么?没有创建实例只是构造函数在对抽象类Person的属性初始化,对于一个类的声明,赋值 和使用两件事情,前者不需要实例化,后者必须实例化
抽象类中的构造方法是怎么回事?就是初始化属性的作用
为什么有构造方法却不能实例化?没有这样的说法,只能针对类实例化对象
抽象类不能被实例化,构造函数被可以重载不能被覆盖,构造函数不能被继承
构造函数和类名相同,所以,继承下来也不是构造函数了,还有构造函数是一个对类初始化的特殊方法,代表这个类,一个基类是不可能知道子类会扩展什么,如果继承了就可以不写代码了,那么子类的新属性怎么初始化?当然这2点是我个人的看法
【三】
在没有好好地研习面向对象设计的设计模式之前,我对Java接口和Java抽象类的认识还是很模糊,很不可理解。
刚学Java语言时,就很难理解为什么要有接口这个概念,虽说是可以实现所谓的多继承,可一个只有方法名,没有方法体的东西,我实现它又有什么用呢?我从它那什么也得不到,除了一些方法名,我直接在具体类里加入这些方法不就行了吗?
为什么一定要有抽象类这个概念?为什么就不能把这个父类写成一个具体的类,子类再继承它不就可以了吗?何必弄一个抽象类出来,还要弄一些没有方法体的抽象方法,弄得又象接口又象类的,让人捉摸不定。
当我开始学习java设计模式,真正走进面向对象设计的大门之后,我才发现,自己对面向对象设计的理解原来是那么的片面,那么的肤浅,根本就没有真正理解面向对象思想的精髓,在某一种程度上还受着面向过程的影响,以为弄出了一个个类,就算是面向对象了,而其实还是被过程所驱使着。
我还是说说我现在对面向对象思想的理解吧,不一定正确全面,但我想应该还算是比以前略有进步吧
面向对象思想,我觉得最关键的就是抽象。
一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了。当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用呢,面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用,是不是一下子感觉自己对复用理解的高度又上升了一层?^_^
说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了,这也是本文我想说的重点。
既然面向对象设计的重点在于抽象,那Java接口和Java抽象类就有它存在的必然性了。
Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。OOP面向对象的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些太有用的抽象类型做为你结构层次上的顶层。
Java接口和Java抽象类有太多相似的地方,又有太多特别的地方,究竟在什么地方,才是它们的最佳位置呢?把它们比较一下,你就可以发现了。
1、Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这大概就是Java抽象类唯一的优点吧,但这个优点非常有用。
如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点。
2、一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣。
在这一点上,Java接口的优势就出来了,任何一个实现了一个Java接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型。
3、从第2点不难看出,Java接口是定义混合类型的理想工具,混合类表明一个类不仅仅具有某个主类型的行为,而且具有其他的次要行为。
4、结合1、2点中抽象类和Java接口的各自优势,具精典的设计模式就出来了:声明类型的工作仍然由Java接口承担,但是同时给出一个Java抽象类,且实现了这个接口,而其他同属于这个抽象类型的具体类可以选择实现这个Java接口,也可以选择继承这个抽象类,也就是说在层次结构中,Java接口在最上面,然后紧跟着抽象类,哈,这下两个的最大优点都能发挥到极至了。这个模式就是“缺省适配模式”。
在Java语言API中用了这种模式,而且全都遵循一定的命名规范:Abstract +接口名。
Java接口和Java抽象类的存在就是为了用于具体类的实现和继承的,如果你准备写一个具体类去继承另一个具体类的话,那你的设计就有很大问题了。Java抽象类就是为了继承而存在的,它的抽象方法就是为了强制子类必须去实现的。
使用Java接口和抽象Java类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。而不要用具体Java类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。
我想,如果你编的代码里面连一个接口和抽象类都没有的话,也许我可以说你根本没有用到任何设计模式,任何一个设计模式都是和抽象分不开的,而抽象与Java接口和抽象Java类又是分不开的。
理解抽象,理解Java接口和抽象Java类,我想就应该是真正开始用面向对象的思想去分析问题,解决问题了吧
分享到:
相关推荐
学生通过对该项目整体框架的搭建和对动物城信息管理等模块的设计与功能实现,训练了学生对项目框架的搭建、类的封装、抽象类定义与继承、接口的定义与接口的实现等Java OOP面向对象知识点的掌握。 本项目主要包括...
在Java面向对象编程(Object-Oriented Programming,简称OOP)中,接口(Interface)是一种重要的抽象机制,它定义了一组方法签名而没有提供具体的实现,从而允许不同的类通过实现同一接口来支持相同的行为,这被...
面向对象与Java实现:抽象类、接口的深度解析 面向对象程序设计(OOP)是现代软件工程中的核心概念,它通过封装、继承、多态等特性来构建灵活、可复用和可扩展的代码结构。Java作为一门广泛使用的面向对象语言,提供...
在Java编程语言中,抽象类和接口是两种面向对象编程(OOP)机制,用以实现抽象概念的不同方式。理解这两者之间的区别对于掌握Java的面向对象特性至关重要,尤其在设计软件架构时。以下将详细分析Java中抽象类和接口...
在"JavaOOP_第1章上机练习.zip"这个压缩包中,我们可以预见到它包含了关于Java OOP的初步学习材料,特别是针对初学者的上机实践练习。 在Java OOP中,有四个核心概念:封装、继承、多态和抽象。这些概念是理解Java ...
7. 抽象类与抽象方法:抽象类不能被实例化,用于提供共同的基类,而抽象方法没有具体实现,由子类完成。理解抽象类和抽象方法的标识符abstract。 8. final关键字:final可以修饰类、变量和方法,表示不可改变或不可...
Java通过接口和抽象类实现多态性,以及方法的重写和重载。 5. 接口:接口是一种完全抽象的类型,它只包含常量和抽象方法的声明。Java中使用`interface`关键字定义接口,类可以通过`implements`接口来实现其方法。 ...
在Java中,多态主要通过方法重写(Override)和抽象类/接口实现。例如,Car类可以有一个抽象方法drive(),SUV和Convertible车可以分别重写这个方法,实现不同的驾驶体验。 5. **构造器**:构造器是类的一个特殊方法...
与抽象类不同,接口不能包含任何非静态成员变量,也不能有方法实现。接口可以看作是多个类之间的契约,实现接口的类必须提供接口中所有方法的具体实现。使用`interface`关键字声明一个接口,例如: ```java public ...
【Java OOP基础和应用:抽象类与final类】 面向对象编程(OOP)是Java的核心,其中抽象类和final类是两个关键概念,它们帮助我们实现代码的封装、继承和多态性。 **5.6.1 抽象类** 抽象类在Java中是一种特殊类型...
在本压缩包“JavaOOP_第2章上机练习.zip”中,主要涉及的是Java面向对象编程(Object-Oriented Programming,简称OOP)的相关知识。Java OOP是Java编程语言的核心特性,它允许我们将复杂的程序设计分解为一系列相互...
5. **抽象类与接口**:抽象类是不能实例化的类,它用于提供子类共享的特性。接口则是一种完全抽象的类型,定义了一组方法签名,强制实现类遵循特定的规范。 6. **构造器**:构造器是类的一个特殊方法,用于初始化新...
第十章可能涵盖了高级OOP概念,如抽象类、接口、内部类和异常处理。抽象类是不能被实例化的类,常用于定义规范,而接口则是一种完全抽象的类型,强制实现特定的方法。内部类可以是成员内部类、局部内部类、匿名内部...
6. **抽象类与接口**: 抽象类是不能被实例化的类,它通常包含抽象方法(没有具体实现的方法)。抽象类用于定义共同特征,供其他类继承。接口则是一种完全抽象的类型,只包含常量和抽象方法,一个类可以实现多个...
抽象则体现在抽象类和接口中,它们提供了不完全实现或不具体实现的结构,允许子类根据需求进行扩展。 在Java中,类是通过关键字`class`来定义的,每个类都包含属性(fields)和方法(methods)。属性是类的状态,...
在Java中,可以通过两种形式来体现OOP(Object Oriented Programming,OOP,面向对象程序设计)的抽象:接口和抽象类。 这两者有太多相似的地方,又有太多不同的地方。很多人在初学的时候会以为它们可以随意互换...
10. 抽象类与接口的比较:抽象类可以包含非抽象方法和字段,而接口不能;一个类可以继承一个抽象类并实现多个接口。 11. 内部类:Java支持嵌套在其他类内部的类,分为成员内部类、局部内部类、匿名内部类等,提供了...
在这个名为"JavaOOP_第6章上机练习.zip"的压缩包中,我们可以预见到包含的是关于Java OOP的第六章练习题目,可能涵盖了类、对象、继承、接口、抽象类、访问修饰符、构造器、方法重写、多态性等相关主题。 1. 类与...
2. 抽象类与接口:抽象类是不能实例化的类,它为其他类提供了一种公共接口。接口是一种完全抽象的类型,只包含常量和抽象方法。类可以通过实现接口来实现多态性,这种方式称为接口多态。一个类可以实现多个接口,...
在这个“javaoop复习.rar”压缩包中,虽然没有直接的标签信息,但我们可以推测它包含了一些用于复习Java OOP概念的资料。让我们深入探讨一下Java OOP中的关键知识点。 1. 类与对象: - **类** 是面向对象编程的...