• 1. 第7课 Java面向对象设计-接口
  • 2. 上节提问什么是overwrite(重写)重写规则是什么 什么是重载(override) 什么是多态 Super的应用场景 解释一下final 什么抽象类 什么是接口 接口里的成员变量有什么特点 如何对一个对象排序.
  • 3. 学习目标理解抽象类的概念; 掌握接口的使用; 理解final关键字;
  • 4. 本课内容抽象类 final 接口
  • 5. 1. 抽象类(abstract class)从继承层次由下而上看,类变得更通用也更抽象,甚至只具备概念上的意义,而并非需要其特定的实例对象,这样更高抽象层次的超类我们把它叫做抽象类。
  • 6. 抽象类我们来看这样一个类层次结构 动物 大象 狮子 之间的关系Animaleat()AnimalAnimaleat()AnimalElephanteat()lioneat()
  • 7. 抽象类现在的问题是Animal类的eat()方法该如何实现
  • 8. Animal类无法实现eat()方法,因为Animal类并不存在一个具体的实体,eat()方法只能由它的具体子类来实现 当您定义类时,可以仅声明方法名称而不实现当中的逻辑,这样的方法称之为「抽象方法」(Abstract method),如果一个类别中包括了抽象方法,则该类别称之为「抽象类别」(Abstract class),抽象类别是个未定义完全的类别,所以它不能被用来生成对象,它只能被子类继承,并于继承后完成未完成的抽象方法定义。
  • 9. 抽象类(abstract class)用abstract关键字来修饰一个类时,这个类叫做抽象类;用abstract来修饰一个方法时,该方法叫做抽象方法。 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。 抽象类不能被实例化。 抽象类一般是一个基础的实现框架 抽象方法只需声明,而不需实现 abstract returnType abstractMethod ( [paramlist] );
  • 10. 抽象类思考A. 非抽象超类能包含抽象方法吗?为什么? 思考B. 抽象类可以包含非抽象方法吗?为什么?应该怎么设计 思考C. 抽象类必须包含抽象方法吗? 思考D. 继承抽象类的抽象类可以实现超类中的抽象方法吗?
  • 11. abstract class Animal { protected int legs; protected Animal(int legs) { this.legs = legs; } abstract void eat(); public void walk() { System.out.println("the animal walk use " + legs + " legs"); } }
  • 12. class Spider extends Animal { Spider() { super(8); } public void eat() { System.out.println("the spider eat"); } } class Cat extends Animal implements Pet { String name; Cat(String name) { super(4); this.name = name; } Cat() { this(""); } public void eat() { System.out.println("the cat eat"); } }
  • 13. 练习:根据类图编写代码:Music4.java
  • 14. 2. 关键字finalfinal可用来修饰类、变量和方法 final变量 基本数据类型,变量的值不可修改 引用数据类型,引用的对象不可修改。某个reference一旦初始化用以代表某个对象后,就再也不能改而指向其他对象,但对象的数据可以被修改 final成员变量练习: FinalData.java
  • 15. class Poppet {int age; }//乖孩子 public class BlankFinal { final int i = 0; // Initialized final final int j; // Blank final final Poppet p; // Blank final reference // Blank finals MUST be initialized in the constructor: BlankFinal(int x) { j = x; p = new Poppet();// Initialize blank final } public static void main(String[] args) { BlankFinal bf = new BlankFinal(11); bf.p.age =12; } }
  • 16. class Gizmo { public void spin() {} } public class FinalArguments { void with(final Gizmo g) { g = new Gizmo(); // Illegal -- g is final } void without(Gizmo g) { g = new Gizmo(); // OK -- g not final g.spin(); } void f(final int i) { i++; } // Can't change // You can only read from a final primitive: int g(final int i) { return i + 1; } public static void main(String[] args) { FinalArguments bf = new FinalArguments(); bf.without(null); bf.with(null); } }
  • 17. class Employee { private String name; public double salary; public final void raiseSalary() { salary *= 1 + 1 / 100; } } final class CEO extends Employee{ public void raiseSalary() { salary *= 1 + 3 / 100; } } class DSZ extends CEO{ }
  • 18. 接口的概念在java程序设计语言中,接口不是类,而是对类一组需求的描述,这些类要遵从接口描述的统一格式进行定义,接口就是说明一组类能做什么,而不关心如何做
  • 19. 接口的概念让规范和实现分离正是接口的好处,让系统的各组件之间通过接口耦合,是一种松耦合的设计。软件系统各模块之间也应该采用这种面向接口的耦合,为系统提供更好的可扩展性和维护性. 因此在java中接口定义的是多个类共同的行为规范,这意味着接口里通常是定义一组方法
  • 20. 接口接口的声明是使用"interface"关键字,声明方式如下: public interface 接口名称 { 零个到多个常量定义 零个到多个抽象方法定义 }
  • 21. 接口定义接口里定义的是多个类共同的公共行为规范,因此接口里所有成员,包括常量、方法都是public访问权限 接口里定义的属性,只能是常量,因此系统会自动为这些属性增加static和final两个修饰符 如下两行代码结果完全一样 int MAX_SIZE=10; public static final int MAX_SIZE=10;
  • 22. 接口
  • 23. 接口 表面上看来,接口有点象是完全没有任何具体方法的抽象类,但实际上两者还是是有差别的。Java中只能单一继承,也就是一次只能继承一个类,Java使用interface来达到某些多重继承的目的,您可以一次实作多个接口 实先多个接口的方式如下: public class 类别名称 implements 接口1, 接口2, 接口3 { // }
  • 24. 当您实现多个接口时,记得您必须实现每一个接口中所定义的方法
  • 25. 接口和抽象类接口和抽象类很像,它们都具有如下特征 1.接口和抽象类都不能被实例化。只能被其他类实现和继承。 2.接口和抽象类都可以包含抽象方法,实现接口和抽象类的类都必须实现这些抽象方法
  • 26. 接口和抽象类接口和抽象类有如下不同 1.接口里只能包含抽象方法,不包含已经实现的方法;抽象类则完全可以包含普通的方法。 2.接口里不能定义静态方法;抽象类可以定义静态方法 3.接口里只能定义静态常量属性,不能定义普通属性;抽象类里则即可以定义普通属性,也可以定义静态常量属性 4.接口不包含构造函数;抽象类可以包含构造函数,抽象类里的构造函数并不是用于创建对象,而是让其子类调用这些构造函数来完成属于抽象类的初始化操作. 5.接口不包含初始化块,但抽象类则完全可以包含初始化块 6.一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补java的单继承不足
  • 27. 接 口接口(interface)是抽象方法和常量值的集合。 接口是一种纯粹的抽象类,只提供对外的界面定义,而不包含任何实现(如变量和方法的实现代码)。
  • 28. 接口“interface”(接口)关键字使抽象的概念更深入了一层。我们可将其想象为一个“纯”抽象类。 接口中的所有方法都是没有方法体的抽象方法,代表一些基本行为。 接口也可以包含基本数据类型的数据成员,但它们都默认为static和final。
  • 29. interface CanFight { void fight(); } interface CanSwim { void swim(); } interface CanFly { void fly(); } class ActionCharacter//动作元素 { public void fight() { System.out.println("actionCharacter"); } }
  • 30. class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly { public void swim() {} public void fly() {} } public class Adventure//冒险家 { static void t(CanFight x) { x.fight(); } static void u(CanSwim x) { x.swim(); } static void v(CanFly x) { x.fly(); } static void w(ActionCharacter x) { x.fight(); } public static void main(String[] args) { Hero i = new Hero(); t(i); // Treat it as a CanFight u(i); // Treat it as a CanSwim v(i); // Treat it as a CanFly w(i); // Treat it as an ActionCharacter } }
  • 31. 练习:按以下类图定义接口及其实现类:Music5.java
  • 32. 多个无关的类可以实现同一个接口;一个类可以实现多个无关的接口,因此用接口可以模拟实现多重继承 与继承关系类似,接口与实现类之间存在多态性 定义Java类的语法格式: < modifier> class < name> [extends < superclass>] [implements < interface>, [< interface>]* ] { < declarations>* } public final class String extends Object implements Serializable, Comparable, CharSequence
  • 33. 接口特性接口可以多重实现; 接口中声明的属性默认为public static final的;也只能是public static final的; 接口中只能定义抽象方法,而且这些方法默认为public的、也只能是public的; 接口可以继承其它的接口,并添加新的属性和抽象方法。
  • 34. 接口的继承 通过继承将多个interface结合为一个新的interface 练习:HorrorShow.java 接口属性定义 接口内的属性自动成为static和final 必须被初始化 练习:Months.java
  • 35. public interface Months { int JANUARY = 1, FEBRUARY = 2, MARCH = 3, APRIL = 4, MAY = 5, JUNE = 6, JULY = 7, AUGUST = 8, SEPTEMBER = 9, OCTOBER = 10, NOVEMBER = 11, DECEMBER = 12; } class M implements Months{ } public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Months m = new M(); m.APRIL; Months.APRIL; } }
  • 36. 接口用法总结通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。 通过接口可以指明多个类需要实现的方法。 通过接口可以了解对象的交互界面,而不需了解对象所对应的类。
  • 37. 为某研究所编写一个通用程序,用来计算每一种交通工具运行1000公里所需的时间, 已知每种交通工具的参数都是3个整数A、B、C的表达式。现有两种工具:Car007 和Plane,其中Car007 的速度运算公式为:A*B/C,Plane 的速度运算公式为:A+B+C。 需要编写三类:ComputeTime.java,Plane.java,Car007.java和接口Common.java, 要求在未来如果增加第3种交通工具的时候,不必修改以前的任何程序,只需要编写新的交通工具的程序。 其运行过程如下,从命令行输入ComputeTime的四个参数,第一个是交通工具的类型, 第二、三、四个参数分别时整数A、B、C,举例如下: 计算Plane的时间:"java ComputeTime Plane 20 30 40" 计算Car007的时间:"java ComputeTime Car007 23 34 45" 如果第3种交通工具为Ship,则只需要编写Ship.java, 运行时输入:"java ComputeTime Ship 22 33 44" 提示:充分利用接口的概念,接口对象充当参数。 提示: 实例化一个对象的另外一种办法: Class.forName("Car").newInstance(); 如需要实例化一个Plane对象的话,则只要调用Class.forName("Plane").newInstance()便可。
  • 38. 再看Arrays类的sort方法Arrays类中的sort方法可以对对象数组进行排序,但要满足下列前提:对象所属的类必须实现Comparable接口 下面是Comparable接口的代码 public interface Comparable { public int compareTo(T o); } 这就是说:任何实现Comparable接口的类都需要包含compareTo方法,并且这个方法的参数可以是任何一种类型,返回一个整数数值。
  • 39. 再看Arrays类的sort方法 现在,假设希望使用Arrays类的sort方法对Student对象数组进行排序,Student类就必须实现Comparable接口 为了让类实现一个接口,通常需要下面两个步骤: 1)将类声明为实现某个接口,需要使用关键字implements 2)对接口中的所有方法进行实现
  • 40. 课后作业请编写一个class,使它拥有一个blank final的java.util.Date对象,请初始化该变量并使用该变量。体会:final使用之前一定需要初始化,并且一旦初始化后就无法改变其引用。 编写一个final类,并尝试继承该类。 请证明:class的载入动作只发生一次。也请证明:class的载入动作发生在产生该类的第一个实例时或其static成员第一次被调用时 编写程序证明interface内的成员被自动设为static和final的; 编写一个Shape接口,至少定义两个方法double area()以及void draw()方法。在另外一个package编写类Circle、Rectangle,实现Shape接口以及java.lang.Comparable接口。测试Circle和Rectangle类