资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,抽象类与接口,抽象方法和抽象类,在类中没有方法体的方法,就是抽象方法。,含有抽象方法的类,即为抽象类。,如果一个子类没有实现抽象基类中所有的抽象方法,则子类也成为一个抽象类。,抽象类中可以没有抽象方法,但是有抽象方法的类必须是抽象类。,构造方法、静态方法、私有方法、final方法不能被声明为抽象的方法。,接口,接口的概念是建立在封装的基础之上。在面向对象程序设计中,封装是指对象的使用者通过预先定义的接口关联到某一对象的服务和数据时,无需知道这些服务是如何实现的。因此接口在面向对象程序设计中有着重要的地位。,在Java中,抽象类和接口(Interface)都是一种接口抽象机制,符合接口的特点。习惯上我们只把Java语法中的接口(Interface)作为接口的窄定义。该接口是一种类型,它定义了能被一个类实现的方法。,接口的概念,接口是指一些方法特征的集合,它关心的是方法的特征定义(例如方法的名称、参数的类型及数量),而不是方法的具体实现。在Java中,抽象类和接口都是一种接口抽象机制,符合接口的特点。,接口提供了一种抽象机制,接口使即插即用变得可能,接口针对抽象而不是针对实现,Java接口,定义接口,实现接口,接口与多重继承,public interface 接口名 extends 祖先接口名 ,返回类型 方法名(参数列表);,.,类型 常量字段名=值;,.,public class 类名 extends 祖先类名,implements 接口名 ,其它接口名.,/类的实现代码,.,下面代码通过实现Writeable接口和Eatable接口的Paper类代码,演示了多重继承的程序设计:,public class Paper implements Eatable,Writeable,public void eat(),System.out.println(撕纸吃,+TASTELESS);,public void write(),System.out.println(在纸上书写:);,接口应用实例,使用接口的好处是便于系统的扩展、维护和重用。接口的使用使得代码模块之间的耦合减弱。具体表现在对象之间的依赖关系弱化为客户服务的关系,即客户对象请求服务,服务对象提供服务,而接口则成了提供服务的一种契约。,没有经验的程序员设计接口时通常会犯合并接口和预留接口这两个错误。根据接口隔离法则,我们在设计接口时不应该强迫客户端依赖于他们用不上的方法,而是应该提供职责明确、功能专一的最小化接口。除非必要,应该严格控制接口宽度,避免接口冗余。,接口,接口中所有的方法都是public abstract。,在接口中声明方法时,不能使用native、static、final、synchronized、private、protected等修饰符。,和public类一样,public接口也必须定义在与接口同名的文件中。,接口,接口中可以有数据成员,这些成员默认都是public static final。,Math.java,interface Math,double PI=3.1415926;,class Arithmetic implements Math,double roundArea(double radius),return PI*radius*radius;,class Student,public static void main(String args),Arithmetic a=new Arithmetic();,System.out.println(a.roundArea(3);,System.out.println(Math.PI);/ok,System.out.println(Arithmetic.PI);/ok,System.out.println(a.PI);/ok,接口,一个接口可以继承自另一个接口。,Java中不允许类的多继承,但允许接口的多继承。,Sofa.java,interface Sittable,void sit();,interface Lie,void sleep();,interface Chair extends Sittable,interface Sofa extends Sittable,Lie,接口,在Java中,一个类可以实现多个接口。,一个类在继承另外一个类的同时,可以实现多个接口。,Sofa.java,/实现多个接口,interface Sittable,void sit();,interface Lie,void sleep();,class Sofa implements Sittable,Lie,public void sit(),public void sleep(),Sofa.java,/在继承类的同时,实现多个接口,interface Sittable,void sit();,interface Lie,void sleep();,interface HealthCare,void massage();,class Chair implements Sittable,public void sit();,class Sofa extends Chair implements Lie,HealthCare,public void sleep();,public void massage();,多态的概念,多态是指在一棵继承树中的类可以有多个同名但不同方法,体以及不同形参的方法。,两种情况:,覆盖:在子类中直接定义和父类同样的属性和方法,但重新编写了方法体,即子类与父类方法的形参与返回值都相同,而内部处理不同,这种方法在使用过程中,Java虚拟机会根据调用这个方法的类来确定哪个方法被调用,重载:同一个类定义中有多个同名的方法,但有不同的形参,而且每个方法有不同的方法体,调用时根据形参的个数和类型来决定调用的是哪个方法,注:不能根据返回值的类型来区分重载的方法,方法的覆盖与重载的区别,方法的覆盖是子类和父类之间的关系,而重载是同一类内部多个方法间的关系,方法的覆盖一般是两个方法间的,而重载时可能有多个重载方法,覆盖的方法有相同的方法名和形参表,而重载的方法只能有相同的方法名,不能有相同的形参表,覆盖时区分方法的是根据调用他的对象,而重载是根据形参来决定调用的是哪个方法,用final修饰的方法是不能被子类覆盖的,只能被重载,publicClassParentspublicvoidprint()System.out.println(“parents”);,publicClassFatherextendsParentspublicvoidprint(),System.out.println(“father”);,publicClassMotherextendsParentspublicvoidprint()System.out.println(“mother”);,publicClassTestpublicvoidfind(Parentsp)p.print();,publicstaticvoidmain(Stringargs)Testt=newTest();Fatherf=newFather();Motherm=newMother();t.find(f);t.find(m);,最后的输出结果分别是father和mother,,将派生类的引用传给基类的引用,然后调用重写方法,基类的引用之所以能够找到应该调用那个派生类的方法,就是因为程序在运行时进行了绑定,。,在Java中,谈论多态就是在讨论方法调用的绑定,绑定就是将一个方法调用同一个方法主体关联起来。在C语言中,方法(在C中称为函数)的绑定是由编译器来实现的,在英文中称为earlybinding(前期绑定),因此,大家自然就会想到相对应的latebinding(后期绑定),这在Java中通常叫做run-timebinding(运行时绑定),运行时绑定的目的就是在代码运行的时候能够判断对象的类型。,多态的作用就是用来将接口和实现分离开,改善代码的组织结构,增强代码的可读性。,多态的一个小结:,Java中除了static和final方法外,其他所有的方法都是运行时绑定的。private方法都被隐式指定为final的,因此final的方法不会在运行时绑定。当在派生类中重写基类中static、final、或private方法时,实质上是创建了一个新的方法。,在派生类中,对于基类中的private方法,最好采用不同的名字。,包含抽象方法的类叫做抽象类。注意定义里面包含这样的意思,只要类中包含一个抽象方法,该类就是抽象类。抽象类在派生中就是作为基类的角色,为不同的子类提供通用的接口。,对象清理的顺序和创建的顺序相反,当然前提是自己想手动清理对象,因为大家都知道Java垃圾回收器。,在基类的构造方法中小心调用基类中被重写的方法,这里涉及到对象初始化顺序。,构造方法是被隐式声明为static方法。,用继承表达行为间的差异,用字段表达状态上的变化。,class,Super,static,String greeting(),return,Goodnight;,String name(),return,Richard;,class,Sub,extends,Super,static,String greeting(),return,Hello;,String name(),return,Dick;,class,Test,public,static,void,main(String args),Super s=,new,Sub();,System.,out,.println(s.,greeting,()+,+s.name();,运行Test 类的结果如下,Goodnight,Dick,试图用子类的静态方法隐藏父类中同样标识的实例方法是不合法的编译器将会报错,试图用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的编译器同样会报错,静态方法和最终方法带关键字final 的方法不能被覆盖,实例方法能够被覆盖,抽象方法必须在具体类中被覆盖,常量的定义,使用关键字final定义常量,例如:,final double PI=3.1415926;,作为一种约定,在定义常量时,通常采用大写形式。,final常量可以在声明的同时赋初值,也可以在构造函数中赋初值。,为了节省内存,我们通常将常量声明为静态的(static)。,当子类中的变量名与父类的相同,原来的变量被遮盖。,方法的覆盖(overriding)和重载(overloading)。,子孙类中定义的方法和祖先类中某个方法同名、,同参数行,则祖先类中的该方法被覆盖;,方法的重载是指一个对象的多态性,即多个方法用相同的名称,但参数行不同。,final在方法之前,防止该方法被覆盖;,final在类之前,标是该类不能被继承;,final在变量之前,定义一个常量。,特殊变量this,this变量代表对象本身,当类中有两个同名变量,一个属于类(类的成员变量),而另一个属于某个特定的方法(方法中的局部变量),使用this区分成员变量和局部变量。,使用this简化构造函数的调用。,特殊变量this,关于实例方法和实例数据成员的进一步说明,一个类所有的实例(对象)调用的成员方法在内存中只有一份拷贝,尽管在内存中可能有多个对象,而数据成员在类的每个对象所在内存中都存在着一份拷贝。this变量允许相同的实例方法为不同的对象工作。,每当调用一个实例方法时,,this,变量将被设置成引用该实例方法的特定的类对象。方法的代码接着会与,this,所代表的对象的特定数据建立关联。,特殊变量super,特殊变量super,提供了对父类的访问。,可以使用super访问父类被子类隐藏的变量或覆盖的方法。,每个子类构造方法的第一条语句,都是隐含地调用super(),如果
展开阅读全文