Presentation is loading. Please wait.

Presentation is loading. Please wait.

第11讲 包和接口(一) 多态的两个实例 包的定义 接口的定义 1/.

Similar presentations


Presentation on theme: "第11讲 包和接口(一) 多态的两个实例 包的定义 接口的定义 1/."— Presentation transcript:

1 第11讲 包和接口(一) 多态的两个实例 包的定义 接口的定义 1/

2 教学目标 掌握合理使用多态来设计简化程序 掌握包的概念 掌握包的定义和包的引用 理解接口的定义和接口的实现方法

3 实例 一:重载的使用 编写一个类,它的功能是计算两个数的和。 要求:编写多个求和方法,实现方法的重载。程序将根据参数的类型自动匹配计算和。
定义了3个add()方法,实现了方法的重载 class Example_Overloading_Add{ int add(int a,int b) { return(a+b); } double add(double x,double y) { return(x+y); } double add(double x,double y,double z) { return(x+y+z); } }

4 实例 一:重载的使用(续) public class Ex6_13{
public static void main(String args[]) { Example_Overloading_Add add=new Example_Overloading_Add(); System.out.println("调用两个整型加法的重载方法"); System.out.println("结果是:"+add.add(3,100)); System.out.println("调用三个双精度型加法的重载方法"); System.out.println("结果是:"+add.add(1.0,23.987,39.369)); System.out.println("调用两个双精度型加法的重载方法"); System.out.println("结果是:"+add.add(59.12,79.123)); } 运行结果: 调用两个整型加法的重载方法 结果是:103 调用三个双精度型加法的重载方法 结果是:64.356 调用两个双精度型加法的重载方法 结果是:

5 实例二:多态的设计 一个小孩得知邻居家养了个宠物,但不知是猫是狗还是鸭子。于是丢一块石头到邻居家院中探明真相。
Animal是一个相对抽象的类。在现实世界中,每个动物都一定属于某个特定的种类,因此,这个类中的sound()成员方法的方法体为空,即本身没有任何特定的操作,只是为了实现多态性而设置。在Dog、Cat和Duck中,覆盖了Animal类中的这个方法,它们根据具体动物的特点发出不同的叫声。小孩丢石头,相当于发出命令调用了宠物类对象的sound()方法。因为小孩并不知道是狗是猫还是鸭子,只知道是宠物。然而实际接收此消息的却是宠物的派生类对象,如果是狗,则输出“Woof Woof”字符串;如果是猫,则输出“Miiaooww”字符串;如果是鸭子,则输出“Quack quackquack”字符串。

6 实例二:多态的设计(续) import java.util.Random; class Animal { //动物类
protected String type; //种类 protected String name; //名称 protected String breed; //品种 public Animal(String type,String name,String breed) { this.type=new String(type); this.name=new String(name); this.breed=new String(breed); } public String toString() { return "This is a "+type+"\nIt's "+name+" the "+breed; } public void sound() {} } 类Animal的sound()方法体为空

7 实例二:多态的设计(续) class Dog extends Animal { //Dog类 public Dog(String name) { super("Dog",name,"Unknow"); } public Dog(String name,String breed) { super("Dog",name,breed); } public void sound() { System.out.println("Woof Woof"); } } class Cat extends Animal { //Cat类 public Cat(String name) { super("Cat",name,"Unknow"); } public Cat(String name,String breed) { super("Cat",name,breed); } public void sound() { System.out.println("Miiaooww"); } class Duck extends Animal { //Duck类 public Duck(String name) { super("Duck",name,"Unknow"); } public Duck(String name,String breed) { super("Duck",name,breed); } public void sound() { System.out.println("Quack quackquack"); } 通过Animal类派生得到的Dog、Cat、Duck类都重新定义了sound()方法,覆盖了父类的sound()方法

8 实例二:多态的设计(续) 不同的Animals对象自动匹配相应的sound()方法。 public class Ex6_14 { //测试类
public static void main(String[] args) { Animal[] theAnimals={ //创建对象数组 new Dog("Rover","Poodle"), new Cat("Max","Abyssinian"), new Duck("Daffy","Aylesbury")}; Animal petChoice; //声明父类的引用 Random select=new Random(); //创建随机数对象 for (int i=0;i<5;i++) { petChoice=theAnimals[select.nextInt(theAnimals.length)]; System.out.println("\nYour Choice:\n"+petChoice); petChoice.sound(); } 运行结果: Your Choice: This is a Dog It's Rover the Poodle Woof Woof 不同的Animals对象自动匹配相应的sound()方法。

9 变量的隐藏和方法的覆盖 子类重新定义一个与从父类继承来的域变量完全相同的变量,称为变量的隐藏。
这里所谓隐藏是指子类拥有两个同名的变量:当子类执行继承自父类的方法时,处理的是继承来的变量;当子类执行自定义的方法时,操作的是自定义的变量,而把继承自父类的变量隐藏了起来。 方法覆盖(Override)即指在子类中重新定义父类中已有的方法。(重写) 子类通过成员变量的隐藏和方法的覆盖可以把父类的状态和行为改变为自身的状态和行为。 方法覆盖时应遵循的原则 覆盖后的方法不能比被覆盖的方法有更严格的访问权限。 覆盖后的方法不能比被覆盖的方法产生更多的异常。

10 上转型对象 我们经常说”老虎是哺乳动物”,”狗是哺乳动物”等。若哺乳类是老虎类的父类,这样说当然正确,但当你说老虎是哺乳动物时,老虎将失掉老虎独有的属性和功能。那么,继承关系可以扼要的表示为:“新class是旧class的一种形式。” 例:假设A类是B类的父类,当用子类创建一个对象,并把这个对象的引用放到父类的对象中时,比如 A a; 或 A a; A=new B(); B b=new B(); a=b; 称这个父类对象是子类对象的上转型对象。

11 上转型对象 对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能。上转型对象具有如下特点:
上转型对象不能操作子类新增的成员变量,失掉了这部分属性;不能使用子类新增的方法,失掉了一些功能 。 上转型对象可以操作子类继承或重写的成员变量,也可以使用子类继承的或重写的方法。 如果子类重写了父类的某个方法后,当对象的上转对象调用这个方法时一定是调用了这个重写的方法,因为程序在运行时知道,这个上转对象的实体是子类创建的,只不过损失了一些功能而已。

12 上转型对象 注:不要将父类创建的对象和子类对象的上转型对象混淆。
新增的变量 新增的方法 继承或重写的变量 继承或重写的方法 注:不要将父类创建的对象和子类对象的上转型对象混淆。 可以将对象的上转型对象再强制转换到一个子类对象,这时该子类对象又具备了子类所给的所有属性和功能。 不可以将父类创建的对象的引用赋值给子类声明的对象,就像不能说 ”哺乳动物是老虎”。

13 class 类人猿 { private int n=100; void crySpeak(String s) { System.out.println(s); } class People extends 类人猿 { void computer(int a,int b) { int c=a*b; System.out.println(c); { System.out.println("**"+s+"**"); class Example4_21 { public static void main(String args[]) { 类人猿 monkey=new People(); monkey.crySpeak("I love this game"); People people=(People)monkey; people.computer(10,10); } monkey.n=1000; monkey.computer(10,10);

14 构造方法的继承 子类可以继承父类的构造方法,遵循以下原则: 无条件继承父类的无参构造方法
如果子类定义了构造方法,在创建对象时,先执行继承自父类的无参构造方法,在执行自己定义的构造方法。 对于父类的有参构造方法,子类可以通过在自己的构造方法中使用super关键字来调用它,但这个调用语句必须是子类构造方法的第一个可执行语句。

15 运行结果是什么? class A{ public A(){ System.out.println("String a"); } } class B extends A{ public B(){ System.out.println("String b"); } class C extends B{ public C(){ System.out.println("String c"); } public class ConstructorTest{ public static void main(String args[]){ C c = new C(); }

16 本章小结 本章介绍了面向对象的两个重要特性:继承和多态。通过extends关键字,可以从一个类派生出另外一个类。在新建一个子类对象时,父类的构造方法首先执行,然后再执行子类的构造方法。所有的类直接或间接继承自Object类,Object类提供了几个常用的方法。final关键字保护了不需要继承的类。覆盖和重载是Java编程常用的两个重要技术。通过覆盖,定义子类时可以对父类的某些方法进行重定义。重载是在类中定义名称相同,而参数不同的方法,方法调用时,程序会自动匹配相应的方法。在重载中要注意的一点是,不能定义名称相同,且参数也完全相同的方法。

17 常用的系统包 (1)java.lang——自动加载 (2)java.io (3)java.awt (4)java.awt.event
(5)java.swing (6)java.util——高级类     (7)java.net      (8)java.applet    (9)java.sql      (10)java.rmi——远程连接      (11)java.security——安全机制  

18 创建包 创建了一个名为mypackage的包 在程序中可以引用上面的系统包,也可以创建自己的包。 package语句的格式如下:
例如:package mypackage; 提示:包名标识符一般均为小写字符组成 说明: (1)包可以嵌套,多层包语句的一般形式如下:        package 包名1[.包名2.包名3.…] 创建包的层次也必须映射到用户的文件系统中。例如声明语句package java.awt.image;定义的包需要存储到用户的当前文件系统的相应文件夹java\awt\image中。 (2)如果源程序中省略了package语句,源文件中定义的类文件就被默认为是无名包的一部分,即源文件中定义的类文件也在一个包中,但是这个包没有名字。

19 Father、Son和Daughter,并放在包family中
package family; class Father{  //类Father装入包family String name; int age; public void drive(){ System.out.println(“I can drive.”); } } class Son{ //类Son装入包family public void play(){ System.out.println(“I can play basketball.”); class Daughter{  //类Daughter装入包family public void paly(){ System.out.println(“I can play tableball.”); 定义一个包,名为family 包的示例 定义了3个类: Father、Son和Daughter,并放在包family中

20 import语句 import 语句的格式如下: import <类名>; 例如: import java.awt.Class;
说明: (1)如果要引入的类很多,且在同一个包中,则可以使用通配符“*”,如: import java.io.*; (2) java.lang这个包无需显式地引用,它总是被编译器自动调入的。

21 import语句示例 编写一个applet程序,实现在屏幕上显示 “import语句的应用实例”。 import java.awt.*;
import java.applet.Applet; public class Ex7_3 extends Applet{ public void paint(Graphics g){ g.drawString("import语句的应用实例",20,20); }

22 再谈作用域修饰符 public修饰的公共变量有较大的作用域,对任何类都是可见的,既允许此变量所属的类访问,也允许同一个包中的其他类访问,还允许其他包中的类访问,所以public修饰的变量不具有保护功能。 protected修饰的变量可以被定义它的类及其同一包中的子类直接访问,也可以由同一包的其他类直接访问。 缺省(default)是指成员变量前没有任何修饰符。一个类缺省修饰符时,它可以被定义它的类及其同一包中的其他类直接访问。 private修饰的成员变量具有很好的封装性,只能被定义它的类访问。

23 为什么是错误的? public class Ex7_4{ public static void main(String arg[]){ {
AClass aClass=new AClass(); aClass.ax=10; //Error aClass.ay=20; //Error aClass.print(); BClass bClass=new BClass(); bClass.bx=15; bClass.by=25; bClass.print(); } } package example; class AClass{ private int ax,ay; public void print() { int result; result=ax+ay; System.out.println("ax+ay="+result); } } class BClass{ public int bx,by; public void print() { result=bx+by; System.out.println("bx+by="+result); } } 为什么是错误的?

24 接口 Java的接口是另一种引用类型,也是面向对象的一个重要机制。引入接口的目的是为了克服Java单继承机制带来的缺陷,同时免除C++中多继承的复杂性。Java的接口在语法上类似于类的一种结构,它只定义一些常量和抽象方法,由接口声明和接口体两部分组成。

25 定义接口 定义格式: [public|abstract] interface 接口名 [extends 接口列表]{ 常量声明;
    常量声明;     抽象方法声明;  } 说明: (1)接口的修饰符可以是public或abstract,其中public或abstract缺省时也有效。 (2)接口也具有继承性。定义接口时可以使用extends关键字定义该新接口是某个已经存在的父接口的派生接口,它将继承父接口的所有属性和方法。

26 接口示例 (3)变量的修饰符只能是public final static,所以在定义时不用显式的使用修饰符。
(4)接口中定义的方法总是abstract的,abstarct缺省也有效。与抽象类一样,接口不需要构造方法。 下面是一个接口定义的例子。 public interface InterfaceExample{ String Name= “Java”; public void programming(); }

27 实现接口 类可以通过关键字implements实现接口,其语法如下:
[类修饰符] class 类名 [extends 父类名] [implements 接口名列表] 说明: 1. 在类的定义部分,如果一个类要实现多个接口,那么接口名之间要用逗号分隔。 2. 如果实现接口的类不是abstract修饰的抽象类,那么在类的定义部分必须实现接口中定义的所有方法,并给出具体的实现代码;反之,可以不实现该接口的所有抽象方法。 3.如果在实现接口的类中所实现的方法与抽象方法有相同的方法名称和不同的参数列表,则只是重载了一个新的方法,并没有实现接口中的抽象方法。

28 接口实现示例 4. 接口的抽象方法的访问修饰符都已规定为public,所以类在实现这些抽象方法时,必须显式地使用public修饰符,否则系统提示出错警告。 interface A{//定义一个接口A char ch='A'; public void print(); } class Aclass implements A{// 实现接口A public void print(){ System.out.println("我实现了接口"+ch); } } public class Ex7_5{ public static void main(String args[]) { Aclass aclass=new Aclass(); aclass.print(); 5. 如果接口中的方法的返回类型不是void,则在类中实现该方法时,方法体中至少要有一条return语句。

29 Collection Collection是在java.util包中的接口,其声明如下:
public interface Collection 常用方法: (1)public boolean add(Object o):将对象添加到集合中 (2)public boolean contains(Object o)查找集合中是否含有对象o (3)public boolean equals(Object o)判断集合是否等价 (4)public Iterator iterator()返回一个迭代器,用来访问集合中的元素 (5)public boolean remove(Object o)删除集合中的对象o (6)public int size()返回集合中元素的个数 (7)public Object[] toArray()以数组的形式返回集合中的元素

30 作业 作业 P157——6、7、8、9


Download ppt "第11讲 包和接口(一) 多态的两个实例 包的定义 接口的定义 1/."

Similar presentations


Ads by Google