第5面向对象高级程序设计.ppt

上传人:本田雅阁 文档编号:2551263 上传时间:2019-04-07 格式:PPT 页数:54 大小:591.01KB
返回 下载 相关 举报
第5面向对象高级程序设计.ppt_第1页
第1页 / 共54页
第5面向对象高级程序设计.ppt_第2页
第2页 / 共54页
第5面向对象高级程序设计.ppt_第3页
第3页 / 共54页
亲,该文档总共54页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《第5面向对象高级程序设计.ppt》由会员分享,可在线阅读,更多相关《第5面向对象高级程序设计.ppt(54页珍藏版)》请在三一文库上搜索。

1、1,第5章 面向对象高级程序设计,2,主要内容,5.1 继承 5.2 多态性 5.3 抽象类和抽象方法 5.4 接口 5.5 内部类和匿名类,3,5.1 继承,5.1.1 创建子类 5.1.2 成员变量的隐藏和方法的重写 5.1.3 super 5.1.4 对象的上转型对象,4,5.1.1 创建子类,继承是一种由已有的类创建新类的机制。利用继承,我们可以先创建一个拥有共同属性的一般类,根据该一般类再创建具有特殊属性的新类。由继承而得到的类称为子类(subclass),被继承的类称为父类(或叫超类,superclass)。 直接或间接被继承的类都是父类。子类继承父类的状态和行为,同时也可以修改父

2、类的状态或重写父类的行为,并添加新的状态和行为。Java中不支持多重继承。,5,5.1.1 创建子类,通过在类的声明中加入extends子句来创建一个类的子类,其格式如下: class SubClass extends SuperClass 上面的代码把SubClass声明为SuperClass的直接子类。如果SuperClass又是某个类的子类,则SubClass同时也是该类的(间接)子类。子类可以继承父类的成员变量和方法。如果缺省extends子句,则该类为java.lang.Object的子类。子类可以继承父类中访问权限设定为public、protected、default的成员变量和方

3、法。但是不能继承访问权限为private的成员变量和方法。,6,5.1.1 创建子类,7,5.1.1 创建子类,Public class MammalClass String name,eyeColor; int age; public MammalClass() name=“the name”; eyeColor=“black”; age=0; ,8,5.1.1 创建子类,注意,MammalClass类拥有来自于DogClass和CatClass的相同属性,包括了name、eyeColor、age等。现在我们可以利用继承重写DogClass和CatClass。 public class Do

4、gClass extends MammalClass boolean hasTail; / name,eyeColor,age已经从父类继承 public DogClass() /隐式调用super() name=“Chase“; eyeColor=“Black“; age=2; hasTail=true; ,9,5.1.1 创建子类,【例5-1】 继承的简单例子 class Father /父类 private int money; float weight,height; String head; String speak(String s) return s ; class Son ex

5、tends Father /子类 String hand ,foot; ,Weight,height,head, Speak(); Hand,foot,10,5.1.1 创建子类,【例5-1】 继承的简单例子 public class TestExtend public static void main(String args) Son boy=new Son(); boy.weight=120f; boy.height=1.8f; boy.head=“一个头“; boy.hand=“两只手“; boy.foot=“两只脚“; System.out.println(“我是儿子“); Syste

6、m.out.println(“我有:“+boy.hand+“、“+boy.foot+“、“+ boy.head +“、重“+boy.weight+“、高“+boy.height); 上面程序运行结果如下: 我是儿子 我有:两只手、两只脚、一个头、重120.0、高1.8,11,5.1.1 创建子类,如果子类和父类不在同一个包中,那么,子类可以继承了父类的protected、public修饰的成员变量做为子类的成员变量,并且也可以继承了父类的protected、 public 修饰的方法作为子类的方法。另外子类和父类不在同一个包中,则子类不能继承父类的default变量和default方法。,12

7、,5.1.1 创建子类,【例5-2】继承不同包中的类的简单例子 / HouseHold.java package xing.house; public class HouseHold /家类 protected String address; /地址 保护型 public String surnname; /姓 公共型 String givenname; /名 缺省 public HouseHold(String add) address =add; protected String getAddress()return address; void setMoney(String newadd

8、) address=newadd; void setAddress(String add)address=add; ,13,5.1.1 创建子类,/ Mikey.java: package xing.friend; import xing.house.HouseHold; public class Mikey extends HouseHold public Mikey() super(“Star flight street 110“); public static void main(String args) Mikey mikey=new Mikey(); /mikey.givenname

9、=“Johnson”; /非法 mikey.surnname=“Math“; /合法. mikey.address=“Star flight street 110“; /合法. String m=mikey.getAddress(); /合法 /mikey.setAddress(“Star flight street 110“); /非法. System.out.println(mikey.surnname+“:“+m); ,14,5.1.1 创建子类,程序编译和运行过程如下:,15,5.1.2 成员变量的隐藏和方法的重写,当我们在子类中定义的成员变量和父类中的成员变量同名时,此时称子类的成员

10、变量隐藏了父类的成员变量。当子类中定义了一个方法,并且这个方法的名字,返回类型,参数个数以及类型和父类的某个方法完全相同时,父类的这个方法将被隐藏,这时我们说重写了父类的方法。 子类通过成员变量的隐藏和方法的重写可以把父类的状态和行为改变为自身的状态和行为。,16,5.1.2 成员变量的隐藏和方法的重写,例如下面的这段程序就是这样的情况: class SuperClass /父类 int y; void setY() y=0; class SubClass extends SuperClass int y; / 父类变量y被隐藏 void setY() / 重写父类的方法setY() y=1;

11、 ,17,5.1.3 super,5.1.3 super 子类在隐藏了父类的成员变量或重写了父类的方法后,常常还要用到父类的成员变量,或在重写的方法中使用父类中被重写的方法以简化代码的编写,这时就要访问父类的成员变量或调用父类的方法,Java中通过super来实现对父类成员的访问。我们知道,this用来引用当前对象,与this类似,super用来引用当前对象的父类。 super的使用可以分为下面三种情况: 1)用来访问父类被隐藏的成员变量,如: super.variable 2)用来调用父类中被重写的方法,如: super.Method(paramlist): 3)用来调用父类的构造方法,如:

12、 super(paramlist);,18,5.1.3 super,【例5-3】调用父类的构造方法的例子 class A /类A public int n; /公共类型的成员变量 public A() public A(int n) this.n = n; int method() return n; public class B extends A /类B public B() super(15); public static void main(String args) A aInstance = new B( ); int b=aInstance.method(); System.out

13、.println(“类A中的成员变量:“+b); ,19,Super的使用-调用父类的方法,class superClass int y; superClass( ) y=30; System.out.println(“in superClass:y=“+y); void doPrint() System.out.println(“In superClass.doPrint()“); ,例子5-4 调用父类的方法,20,class subClass extends superClass int y; subClass( ) super(); /调用父类的构造方法(多余的) y=50; Syst

14、em.out.println(“in subClass:y=“+y); void doPrint( ) super.doPrint(); /调用父类的方法 System.out.println(“in subClass.doPrint()“); System.out.println(“super.y=“+super.y+“ sub.y=“+y); public class inviteSuper public static void main(String args) subClass subSC=new subClass(); subSC.doPrint( ); ,21,5.1.4对象的上转

15、型对象,假设A 类是B 类的父类, class B extends A 当我们用子类创建一个对象,并把这个对象的引用放到父类的对象中时,例如 A a; A a=new B(); 或 A a; B b=new B(); a=b; 称这个父类对象a,是子类对象b的上转型对象。,22,5.1.4对象的上转型对象,对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能。上转型对象具有如下特点: 1)上转型对象不能操作子类新增的成员变量和子类新增的方法。 2)上转型对象可以操作子类继承或重写的成员变量,也可以使用子类继承的或重写的方法。 3)如果子类重写了父类的某个方法后,当对

16、象的上转对象调用这个方法时一定是调用了这个重写的方法,因为程序在运行时知道,这个上转对象的实体是子类创建的,只不过损失了一些功能而已。 不要将父类创建的对象和子类对象的上转型对象相混淆。 上转型对象在Java编程中是常见的。 可以将对象的上转型对象再强制转换到一个子类对象,这时,该子类对象又具备了子类所给的所有属性和功能。,23,5.1.4对象的上转型对象,【例5-5】 上转型对象的使用 class Mammal /哺乳动物类 private int n=40; void crySpeak(String s) System.out.println(s); public class Monkey

17、 extends Mammal / 猴子类 void computer(int aa,int bb) int cc=aa*bb; System.out.println(cc); void crySpeak(String s) System.out.println(“*“+s+“*“); public static void main(String args) / mammal是Monkey类的对象的上转型对象. Mammal mammal=new Monkey(); mammal.crySpeak(“I love this game“); / puter(10,10); /把上转型对象强制转化

18、为子类的对象. Monkey monkey=(Monkey)mammal; puter(10,10); ,24,5.1.4对象的上转型对象,上述程序的运行结果为: *I love this game* 100 在上述例子中,上转对象mammal调用方法: mammal.crySpeak(“I love this game“); 得到的结果是”*I love this game*”。而不是“I love this game”。因为mammal调用的是子类重写的方法crySpeak。 在main()中,如果出现下面的两行代码,那将是错误的: mammal.n=1000; /因为子类本来就没有继承n

19、。 puter(10,10); /因为computer方法是子类新增的方法。,25,第5章 面向对象高级程序设计,5.1 继承 5.2多态性 5.3 抽象类和抽象方法 5.4接口 5.5内部类和匿名类,26,5.2多态性,多态(Polymorphism)的意思就是用相同的名字来定义不同的方法。在Java中,普通类型的多态为重载,这就意味着可以使几个不同的方法使用相同的名字,这些方法以参数的个数不同、参数的类型不同等方面来进行区分,以使得编译器能够进行识别。 重载是Java实现多态性的方式之一。 例如:family()方法可以有三个版本,如下: family() family(String ch

20、) address=ch; family(String ch,float n) address=ch; pay=n; 这些方法并存于程序中,编译时,编译器根据实参的类型和个数来区分从而调用那个方法。这在其它语言的程序中,如C,那将导致灾难性的错误。,27,5.2多态性,【例5-6】构造方法重载的例子 class person String name=“Johnson“; / 姓名 int age=45; / 年龄 person() person(String a) name=a; person(String a,int b) name=a; age=b; public void display

21、() System.out.println(“Name=“+name+“,“+“Age=“+age); public class Poly public static void main(String args) person ko1=new person(); ko1.display(); person ko2=new person(“Mike“); Ko2.display(); person ko3=new person(“Willian“,50); ko3.display(); ,28,5.2多态性,在Java语言中,多态性主要体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方

22、法重写实现的动态多态性(运行时多态),如下: 1) 编译时多态 在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。 2) 运行时多态 如果子类重写了父类的方法,那么重写方法的调用原则如下:Java运行时系统根据调用该方法的实例,来决定调用哪个方法。对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;如果子类继承了父类的方法(未重写),则运行时系统调用父类的方法。 另外,方法重写时应遵循的原则如下: 改写后的方法不能比被重写的方法有更严格的访问权限。 改写后的方法不能比被重写的方法产生更多的异常。 进行方法重写时必须遵从这两个原则,否则编译

23、器会指出程序出错。,29,5.2多态性,【例5-7】方法重写的例子 class Parent public void function() System.out.println(“I am in Parent!“); class Child extends Parent private void function() System.out.println(“I am in Child!“); public class RTpolyTest public static void main(String args) Parent pl=new Parent( ); Parent p2=new Ch

24、ild( ); p1.function( ); p2.function( ); ,30,5.2多态性,编译过程如下: D:userchap05Javac RTpolyTest.java RTpolyTest.java:8: function() in Child cannot override function() in Parent; attempting to assign weaker access privileges; was public private void function() RTpolyTest.java:16: cannot find symbol symbol :

25、variable p1 location: class RTpolyTest p1.function( ); 2 errors 可以看出,该程序中实例p2调用function()方法时会导致访问权限的冲突。,31,第5章 面向对象高级程序设计,5.1 继承 5.2多态性 5.3 抽象类和抽象方法 5.4接口 5.5内部类和匿名类,32,5.3 抽象类和抽象方法,Java语言中,用abstract关键字来修饰一个类时,这个类叫做抽象类。一个abstract 类只关心它的子类是否具有某种功能,并不关心该功能的具体实现,功能的具体行为由子类负责实现的。例如: public abstract clas

26、s Drawing public abstract void drawDot(int x, int y); public void drawLine(int x1, int y1,int x2, int y2) 用abstract来修饰一个方法时,该方法叫做抽象方法。与final类和方法相反,abstract类必须被继承,abstract方法必须被重写。,33,5.3 抽象类和抽象方法,当一个类的定义完全表示抽象的概念时,它不应该被实例化为一个对象。例如Java中的Number类就是一个抽象类,它只表示数字这一抽象概念,只有当它作为整数类Integer或实数类Float等的父类时才有意义。 定

27、义一个抽象类的格式如下: abstract class abstractClass 由于抽象类不能被实例化,因此下面的语句会产生编译错误: new abstractClass(); 抽象类中可以包含抽象方法,为所有子类定义一个统一的接口,对抽象方法只需声明,而不需实现,因此它没有方法体。其格式如下: abstract returnType abstractMethod(paramlist);,34,使用abstract的另一例子,abstract class AA abstract void callme( ); void metoo( ) System.out.println(“Inside

28、As metoo() method“); class BB extends AA void callme( ) System.out.println(“Inside Bs callme() method“); public class AAbstract public static void main(String args) AA cc=new BB(); /cc为上转型对象 cc.callme(); cc.metoo(); ,35,第5章 面向对象高级程序设计,5.1 继承 5.2多态性 5.3 抽象类和抽象方法 5.4接口 5.5内部类和匿名类,36,5.4 接口,5.4.1接口定义 5

29、.4.2使用接口的优点,37,5.4.1接口声明,使用关键字interface 来定义一个接口。接口的定义和类的定义很相似,分为接口声明和接口体两部分。 1、 接口声明 接口通过使用关键字interface 来声明。完整的接口定义格式如下: public interface interfaceName extends listOfSuperInterface 其中public修饰符指明任意类均可以使用这个接口,缺省情况下,只有与该接口定义在同一个包中的类才可以访问这个接口。extends子句与类声明中的extends子句基本相同,不同的是一个接口可以有多个父接口,用逗号隔开,而一个类只能有一个

30、父类。子接口继承父接口中所有的常量和方法。 通常接口名称以able或ible结尾,表明接口能完成一定的行为,例如Runnable、Serializable。,38,5.4.1接口声明,2、 接口体 接口体中包含常量定义和方法定义两部分。其中常量定义部分定义的常量均具有public、static和final属性。其格式如下: returnType methodName(paramlist); 接口中只能进行方法的声明,而不提供方法的实现,所以,方法定义没有方法体,且用分号(;)结尾,在接口中声明的方法具有public和abstract属性。另外,如果在子接口中定义了和父接口同名的常量,则父接口中

31、的常量被隐藏。 例如: interface Summaryable final int MAX=50; / MAX具有public、static、final属性 void printone(float x); float sum(float x ,float y); 上面这段程序可以以Summaryable.java来保存,也可以写入其它Java程序中。,39,5.4.1接口声明,3、接口的使用 一个类通过使用关键字implements 声明自己使用(或实现)一个或多个接口。如果使用多个接口,用逗号隔开接口名。如 class Calculate extends Computer impleme

32、nts Summary,Substractable 类Calculate使用了Summary 和Substractable接口,继承了Computer类。 如果一个类使用了某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体。需要注意的如下: 1)在类中实现接口的方法时,方法的名字,返回类型,参数个数及类型必须与接口中的完全一致。 2)接口中的方法被默认是public ,所以类在实现接口方法时,一定要用public 来修饰。 3)另外,如果接口的方法的返回类型如果不是void 的,那么在类中实现该接口方法时,方法体至少要有一个return 语句。如果是void 型,类体除了两个

33、大括号外,也可以没有任何语句.,40,5.4.1使用接口的优点,从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。通过接口使得处于不同层次,甚至互不相关的类可以具有相同的行为。接口其实就是方法定义和常量值的集合。 它的优点主要体现在下面几个方面: (1)通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。 (2)通过接口可以指明多个类需要实现的方法。 (3)通过接口可以了解对象的交互界面,而不需了解对象所对应的类。 接口把方法的定义和类的层次区分开来,通过它可以在运行时动态地定位所调用的方法。同时接口中可以实现“多重继承”,且一个

34、类可以实现多个接口。正是这些机制使得接口提供了比多重继承(如C+等语言)更简单、更灵活、而且更强劲的功能。,41,5.4.2使用接口的例子,【例5-9】 使用多重接口的例子 / MultInterfaces.java interface I1 abstract void test(int i); /可以去掉的 interface I2 abstract void test(String s); public class MultInterfaces implements I1, I2 public void test(int i) System.out.println(“In MultInte

35、rfaces.I1.test“); public void test(String s) System.out.println(“In MultInterfaces.I2.test“); public static void main(String a) MultInterfaces t = new MultInterfaces(); t.test(42); t.test(“Hello“); ,42,第5章 面向对象高级程序设计,5.1 继承 5.2多态性 5.3 抽象类和抽象方法 5.4接口 5.5内部类和匿名类,43,5.5内部类和匿名类,5.5.1 内部类的定义 5.5.2 内部类特性

36、5.5.3 匿名类,44,5.5.1 内部类的定义,简单地说,一个类被嵌套定义于另一个类中,称为嵌套类。在大多数情况下,嵌套类( 静态的嵌套类除外)就是内部类(inner class)。包含内部类的类称为外部类。与一般的类相同,内部类具有自己的成员变量和成员方法。通过建立内部类的对象,可以存取其成员变量和调用其成员方法。 例如下面的例子: pubic class GroupOne int count; /外部类的成员变量 public class Student /声明内部类 String name; /内部类的成员变量 public void output() /内部类的成员方法 Syste

37、m.out.println(this.name+“ “); ,45,5.5.1 内部类的定义,实际上,Java语言规范对于内部类有如下的规定: 在另一个类或者一个接口中声明一个类。 在另一个接口或者一个类中声明一个接口。 在一个方法中声明一个类。 类和接口声明可嵌套任意深度。 从上面的规定中我们可以看出,内部类的定义是非常灵活的。,46,5.5.2内部类特性,内部类有如下特性: 一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。名称不能与包含它的类名相同。 可以使用包含它的外部类的静态成员变量和实例成员变量,也可以使用它所在方法的局部变量。 可以定义为abstract。 可以声

38、明为private或protected。 若被声明为static,就变成了顶层类,不能再使用局部变量。 若想在内部类中声明任何static成员,则该内部类必须声明为static。 因此外部类与内部类的访问原则是:在外部类中,通过一个内部类的对象引用内部类中的成员;反之,在内部类中可以直接引用它的外部类的成员,包括静态成员、实例成员及私有成员。,47,【例5-10】 内部类和外部类之间的访问,public class GroupTwo /例5-10 private int count; /外部类的私有成员变量 public class Student /声明内部类 String name; pu

39、blic Student(String n1) name=n1; count+; /存取其外部类的成员变量 public void output() System.out.println(this.name); public void output() /外部类的实例成员方法 Student s1=new Student(“Johnson“); /建立内部类对象“ s1.output(); /通过s1调用内部类的成员方法 System.out.println(“count=“+this.count); public static void main(String args) GroupTwo

40、g2=new GroupTwo(); g2.output(); ,48,【例5-11】内部类访问外部静态变量,public class GroupThree private static int count; /静态变量GroupThree.count统计班级数量 private String name; /实例变量GroupThree.name表示班级名称 public class Student private int count; /实例变量Student.count表示学号 private String name; /实例变量Student.name表示学生姓名 public void

41、 Output(int count) count+; /存取方法的参数,局部变量 this.count+; /通过对象存取Student.count GroupThree.count+; /通过类名存取GroupThree.count GroupThree.this.count+; /通过对象名存取GroupThree.count System.out.println(count+“+this.count+“+ GroupThree.count+“+GroupThree.this.count+); public Student aStu() /返回内部类Student的一个对象 return

42、new Student(); public static void main(String args) GroupThree g3=new GroupThree (); g3.count=10; /GroupThree.count GroupThree.Student s1=g3.aStu(); /在外部创建内部类的对象 s1.Output(5); /完整的内部类标识GroupThree.Student ,49,【例5-12】静态公用内部类,public class GroupFour public static class Student /定义静态公用内部类 static int coun

43、t; /静态内部类中的静态变量 String name; int number; /序号 public Student(String n1) /静态内部类的构造方法 name=n1; count+; number=count; /序号自动增加 public void output() System.out.println(this.name+“ number=“+this.number); public static void main(String args) GroupFour.Student s1=new GroupFour.Student(“A“); s1.output(); Grou

44、pFour.Student s2=new GroupFour.Student(“B“); s2.output(); ,50,【例5-13】抽象内部类,public class GroupFive public abstract class Student_abstract /抽象内部类 int count; String name; public abstract void output(); /抽象方法 public class Student extends Student_abstract /继承抽象内部类 public Student(String n1) name=n1; count

45、+; /Student.count public void output() /实现抽象方法 System.out.println(this.name+“ count=“+this.count); public GroupFive() Student s1=new Student(“A“); s1.output(); Student s2=new Student(“B“); s2.output(); public static void main(String args) GroupFive g5=new GroupFive(); ,51,【例5-14】内部接口,public class Gr

46、oupSix public interface Student_info /内部接口 public void output(); public class Student implements Student_info /内部类实现内部接口 int count; String name; public Student(String n1) name=n1; count+; public void output() /实现接口方法 System.out.println(this.name+“ count=“+this.count); public GroupSix(String name1) S

47、tudent s1; int i=0; while(iname1.length) s1=new Student(name1i); s1.output(); i+; public static void main(String args) String arr=“A“,“B“,“C“; GroupSix g6= new GroupSix(arr); ,52,【例5-15】局部内部类,interface Destination String readLabel(); public class GoodsSeven public Destination dest(String s) /方法里面包含一个类 class GDestination implements Destination private String label; private GDestination(String whereTo) label =

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1