收藏 分享(赏)

1_09 Java 面向对象的封装 继承 多态(2).docx

上传人:dzzj200808 文档编号:2278875 上传时间:2018-09-09 格式:DOCX 页数:54 大小:41.23KB
下载 相关 举报
1_09 Java 面向对象的封装 继承 多态(2).docx_第1页
第1页 / 共54页
1_09 Java 面向对象的封装 继承 多态(2).docx_第2页
第2页 / 共54页
1_09 Java 面向对象的封装 继承 多态(2).docx_第3页
第3页 / 共54页
1_09 Java 面向对象的封装 继承 多态(2).docx_第4页
第4页 / 共54页
1_09 Java 面向对象的封装 继承 多态(2).docx_第5页
第5页 / 共54页
点击查看更多>>
资源描述

1、封装,接口,继承,覆盖,构造过程,多态,static 、this、super、final 用法一、封装 (encapsulation) 定义:封装就是将客户端不应看到的信息包裹起来。使内部执行对外部来看不一种不透明的、是一个黑箱,客户端不需要内部资源就能达到他的目的。1事物的内部实现细节隐藏起来 2对外提供一致的公共的接口间接访问隐藏数据 3可维护性 -二、 继承 (inherit) JAVA 继承特点 继承:父类的成员能否继承到子类? 对类成员访问的限制及子类继承情况: (从严 到宽 )private 私有,本类内部 不能继承(default) 本类同包 同包子类可继承 protected

2、本类同包子类 可以继承public 公开 任何地方都可以访问 能继承到子类 -覆盖 1、定义: 覆盖了一个方法并且对其重写,以求达到不同的作用。2、用法:a、最熟悉的覆盖就是对接口方法的实现b、在继承中也可能会在子类覆盖父类中的方法3、产生 “覆盖”的条件:1、方法名:相同 2、参数表:相同(个数,类型) 3、访问限制符:相同或者更宽 4、返回值类型:相同 或者 子类返回的类型是父类返回的类型的子类 5、不能抛出比 subclass(父类)更多的异常 注意:当我们在子类中创建的静态方法,它并不会覆盖父类中相同名字的静态方法。class Parentpublic void nonStaticMe

3、thod()System.out.println(“Parents Non-Static Method is Called“); public static void staticMethod()System.out.println(“parents static method is called“); class Child extends Parentpublic void nonStaticMethod()System.out.println(“childs non-static method is called“); public static void staticMethod()S

4、ystem.out.println(“childs static method is called“); public class Testpublic static void main(String args) Parent p1 = new Parent();Parent p2 = new Child();Child c = new Child();System.out.print(“Parent.static: “); Parent.staticMethod();System.out.print(“p1.static: “); p1.staticMethod();System.out.p

5、rint(“p2.static: “); p2.staticMethod();System.out.print(“p1.nonStatic: “); p1.nonStaticMethod();System.out.print(“p2.nonStatic: “); p2.nonStaticMethod();System.out.print(“Child.static: “); Child.staticMethod();System.out.print(“c.static: “); c.staticMethod();System.out.print(“c.nonStatic: “); c.nonS

6、taticMethod();程序的运行结果为:Parent.static: parents static method is calledp1.static: parents static method is calledp2.static: parents static method is calledp1.nonStatic: Parents Non-Static Method is Calledp2.nonStatic: childs non-static method is calledChild.static: childs static method is calledc.stat

7、ic: childs static method is calledc.nonStatic: childs non-static method is called值得注意的是 p2 实际上是一个 Child 的类型的引用,然而在调用静态方法的时候,它执行的却是父类的静态方法,而不是 Child 的静态方法,而调用 p2 的非静态方法的时候执行的是 Child 的非静态方法,为什么呢?原因是静态方法是在编译的时候把静态方法和类的引用类型进行匹配,而不是在运行的时候和类引用进行匹配。因此我们得出结论:当我们在子类中创建的静态方法,它并不会覆盖父类中相同名字的静态方法。 -构造(java 编程思想定

8、义为:构造器初始化)对象的构造过程: 首先为对象分配内存空间,包括其所有父类的可见或不可见的变量的空间,并初始化这些变量为默认值,如 int 类型为 0,boolean 类型为 false,对象类型为null。 然后用下述 5 个步骤来初始化这个新对象:1)分配参数给指定的构造方法;2)如果这个指定的构造方法的第一个语句是用 this 指针显式地调用本类的其它构造方法,则递归执行这 5 个 步骤;如果执行过程正常则跳到步骤 5;3)如果构造方法的第一个语句没有显式调用本类的其它构造方法,并且本类不是 Object 类(Object 是所有其它类的祖先),则调用显式(用 super 指针)或隐式

9、地指定的父类的构造方法,递归执行这 5 个步骤;如果执行过程正常则跳到步骤5;4)按照变量在类内的定义顺序来初始化本类的变量,如果执行过程正常则跳到步骤 5;5)执行这个构造方法中余下的语句,如果执行过程正常则过程结束。对分析本文的实例最重要的,用一句话说,就是“父类的构造方法调用发生在子类的变量初始化之前”。可以用下面的例子来证明:列 1class Animal Animal() System.out.println(“Animal“);class Cat extends Animal Cat() System.out.println(“Cat“);class Store Store()Sy

10、stem.out.println(“Store“);public class Petstore extends StoreCat cat = new Cat();Petstore()System.out.println(“Petstore“);public static void main(String args) new Petstore();运行这段代码,它的执行结果如下:StoreAnimalCatPetstore从结果中可以看出,在创建一个 Petstore 类的实例时,首先调用了它的父类 Store的构造方法;然后试图创建并初始化变量 cat;在创建 cat 时,首先调用了 Cat

11、类的父类 Animal 的构造方法;其后才是 Cat 的构造方法主体,最后才是 Petstore 类的构造方法的主体。列 2class Animal Animal() System.out.println(“Animal“);class Cat extends AnimalCat()System.out.println(“Cat“);class Cat2 extends AnimalCat2()System.out.println(“Cat2“);class Store Cat2 cat=new Cat2();Store() System.out.println(“Store“);public

12、 class Petstore extends StoreCat cat = new Cat();Petstore()System.out.println(“Petstore“);public static void main(String args) new Petstore();运行这段代码,它的执行结果如下:AnimalCat2StoreAnimalCatPetstore这例 1 和例 2,使我更了解了类的构造过程:类在 new 实例的时候a。第一步构造类的成员变量这里需要注意的:a)即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造函数)被调用之前得到初始化b)初始化的顺序

13、是先“ 静态”对象(初始化过后,静态对象不会再被初始化),而后是“非静态”对象。第二步调用构造方法。b。如果有父类,那么就是先构造父类的成员变量,然后再调用父类的构造方法,然后再 a。-this 用法java 中的 this 随处可见,用法也多,现在整理有几点:1. this 是指当前对象自己。 当在一个类中要明确指出使用对象自己的的变量或函数时就应该加上 this 引用。如下面这个例子中: public class HelloString s = “Hello“; public Hello(String s) System.out.println(“s = “ + s); System.ou

14、t.println(“1 - this.s = “ + this.s); this.s = s; System.out.println(“2 - this.s = “ + this.s); public static void main(String args) Hello x=new Hello(“HelloWorld!“); 运行结果:s = HelloWorld! 1 - this.s = Hello 2 - this.s = HelloWorld! 在这个例子中,构造函数 Hello 中,参数 s 与类 Hello 的变量 s 同名,这时如果直接对 s 进行操作则是对参数 s 进行操作

15、。若要对类 Hello 的成员变量 s 进行操作就应该用 this 进行引用 class A public A() new B(this).print(); public void print() System.out.println(“Hello from A!“); class B A a; public B(A a) this.a = a; public void print() a.print(); System.out.println(“Hello from B!“); public class Cpublic static void main(String args)A x=new

16、 A();运行结果: Hello from A! Hello from B! 在这个例子中,对象 A 的构造函数中,用 new B(this)把对象 A 自己作为参数传递给了对象 B 的构造函数。2。在构造函数中,通过 this 可以调用同一 class 中别的构造函数,如class Flower Flower (int pig)System.out.println(“pig:“+ pig ); Flower(String ss)ss=“string“;System.out.println(“ss:“+ ss); Flower(int pig, String ss) this(pig); Sy

17、stem.out.println(“pigpig“+ pig); public class Zxpublic static void main(String args)Flower a=new Flower(7,“java“);运行结果:pig:7;pigpig:7;值得注意的是:1:在构造调用另一个构造函数,调用动作必须置于最起始的位置。2:不能在构造函数以外的任何函数内调用构造函数。 -static 1. 调用静态方法时,不需要产生对象 .因为静态方法属于类本身 ,而不属于对象. 调用时: 类名.静态方法名() 就可以2. class Pointint x;static int y; /定

18、义了 1 个静态变量static void output()System.out.println(“out“);public static void main(String args) Point.output(); /调用静态方法Point pt1=new point();Point pt2=new point();pt1.y=5;pt2.y=6;System.out.println(pt1.y);System.out.println(pt2.y);结果pt1 6pt2 6静态常量和静态方法,都只属于某个类,加载的时候 已经有内存空间了.所有对象都共享同 1 个静态变量 ,同 1 个静态方法

19、引用直接通过类名引用.但非静态方法,可以调用静态方法和静态变量;但反过来,静态方法不能调用非静态变量和非静态方法.(即 x)-finalfinal 类不能被继承,因此 final 类的成员方法没有机会被覆盖,默认都是 final 的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为 final 类。1.定义及编程技巧final 类不能被继承,没有子类,final 类中的方法默认是 final 的。 final 方法不能被子类的方法覆盖,但可以被继承。 final 成员变量表示常量,只能被赋值一次,赋值后值不再改变。 final 不能用于修饰

20、构造方法。 注意:父类的 private 成员方法是不能被子类方法覆盖的,因此 private 类型的方法默认是 final 类型的2、final 方法 如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为 final 方法。 使用 final 方法的原因有二: 第一、把方法锁定,防止任何继承类修改它的意义和实现。 第二、高效。编译器在遇到调用 final 方法时候会转入内嵌机制,大大提高执行效率。技巧:final static 类型成员变量。static 使得变量只存在一个拷贝。final 使得它不能改变。3.关于 final 成员赋值的讨论:a.final 成员能且只能被初始化一次b

21、.final 成员必须在声明时或者在构造方法中被初始化,而不能在其它的地方被初始化。eg1public class Aoxint height;Aox(int h)height=h; void bb()System.out.println(height); public static void main(String args)Aox boxobj = new Aox(25);boxobj.bb();boxobj=new Aox(32);boxobj.bb();运行结果:2532 eg2public class Aoxint height;Aox(int h)height=h; void bb

22、()System.out.println(height); public static void main(String args)Aox boxobj = new Aox(25);boxobj.bb();/ boxobj=new Aox(32); 出错!boxobj.bb();-super 1.super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 2.super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时)如:super. 变量名 super.成员函数据名(实参) -包1.从本质上来说,包是将类

23、组合在一起形成代码模块的一种机制,可以将包看成一个“文件夹”,而包里的各类,则是“文件”。用途:避免命名冲突;可以在更广的范围保护类,数据和方法。2.创建包package a; /a 是包名3.导入包1) import package a.* /a 是包名。字符“*“则导入了包里的所有类和接口。2) import package a.b /a 是包名,b 是类名。该操作导入了 a 包里的 b 类,而不会导入其它类。4.使用其它包的类,而没有用 import 导入该包,操作如下:a.b x new a.b(); /a 是包名,b 是 a 包里的类,x 是刚创建的该类的实例名。怎样理解封装,继承,

24、多态!三者的区别?封装:每个对象都包括进行操作所需要的所有信息,而不依赖于其他对象来完成自己的操作。通过类的实例来实现。 好处:良好的封装可以降低耦合度;类的内部可以自由修改;类具有对外的清晰接口。 继承:IS-A 的关系。 A is-a B:A 是 B,A 可以继承 B。A 是 B 的一个特例,特殊化,A 又可以具备自己独有的个性。三点: 子类拥有父类非 private 的属性和功能(父类的构造函数例外,可以用 base 关键字访问,base 代表着父类); 子类具有自己的属性和功能,即子类可以扩展父类没有的属性和功能; 子类可以以自己的方式重写父类的功能。 缺点:父类变,子类不得不变,父子

25、是一种强耦合的关系。 多态:不同的对象可以执行相同的动作,但要通过他们自己的实现代码来执行。注意点: 子类以父类的身份出现; 子类在运行时以自己的方式实现; 子类以父类的身份出现时,子类特有的属性和方法不可以使用。 为了使子类的实例完全接替来自父类的类成员,父类必须将该成员声明为虚拟的(virtual ),子类可以选择使用 override 将父类的实现替换为自己的实现,这就是多态。 1。类是对对象的一个抽象,同时类也为对象进行了封装。所谓封装是说类的设计者只是为使用者提供类 对象可以访问的部分,而对于类中其他隐藏起来的成员变量 方法,用户不能访问。 实现方式:A:在类的定义中设置对对象中成员

26、变量和方法进行访问的权限; B:提供一个统一的供其他类引用的方法; C:其它对象不能直接修改文本对象所拥有的属性和方法。 2。访问权限: A:private 的成员变量和方法只能被这个类本身的方法访问; B:默认的成员变量和方法只被同一个包内的其它所有类都可访问,包外不可; C: protected 的成员可以被这个类的本身、它的子类(同不同包均可)访问; D: public 完全公开。一个程序里最多只能有一个类被修饰为 public,若程序中没有任何 public 类,且文件名是程序中的一个类名,则该类被视做 public 注:不能用 protected 和 private 饰! 3。类的继

27、承: 3.1 类继承的实现: A:java 中 Object 类是 java 中所有类的祖宗!(P209) 儿子 A extends 老爸-只能有一个老爸! 3.2 this 和 super: this: this.数据成员 this.实例方法 this(参数)-引用本类中其他构造方法。 super:表示当前对象父类对象的引用 super.数据成员 super.实例方法 super(参数)-引用父类的构造方法。-通常在实现子 类的构造方法时,要先调用父类的构造方法!并且用来调用父类构造方法的 super()必须放在子类构造方法的句首 3.3 初始化顺序: A 对象的初始化顺序: 先静态成员,再

28、非静态成员,再构造方法, B 继承中构造方法的调用顺序: 先父类,再子类。 3.4 对象之间的类型转换: 对象转换的圣经:只能说猫是哺乳动物,不能说哺乳动物是猫!当说猫是哺乳动物时,猫将失掉猫独有的属性和行为!(作为猫时新增的成员变量和方法) 哺乳动物 aa=new 猫()-猫是哺乳动物(要通过 IS-A 测试) 4.千呼万唤始出来-多态! 所谓多态就是同一方法获得不同的行为特性! 分为: A 编译时多态性 -重载 (参数个数不同或参数类型不同) B 动态多态性 -覆盖( 改写后的方法不能比覆盖的方法有更严格的访问权限-只能更加开放 programName 是要引用的程序名,以方法的形式出现。

29、由于是引用,具体执行的操作都包含在源程序中,所有 programName 后无具体方法体! * 一。深入继承: 1设计继承树: (1)找出具有共同属性和行为的对象(狼和狗与羊-动物共同的属性) (2)设计代表共同状态与行为的类(都属于动物!- 父类) (3)决定子类是否需要让某项行为有特定不同运作的方式( 都会吃,但羊只吃草-方法的覆盖) (4)通过寻找使用共同行为的子类找出更多抽象化的机会( 狼和狗属于犬科!-再继承) (5)检查设计是否合理(IS-A) (6)大功告成! 2继承的意义: (1)避免了重复的代码(子类会时时响应父类的改变) (2)定义出共同的协议(服务于多态) ?当定主义出一

30、组类的父型时,你可以用子型的任何类来填补任何需要或期待父型的位置? 二。深入多态: (1) class Vet public void giveShot(Animal a) a.makeNoise(); class PetOwner public void start() Vet v=new Vet(); Dog d=new Dog(); Hippo h=new Hippo(); v.giveShot(d); V.giveSHot(h); 在此例中如果用 Animal 类型来声明它的参数(返回类型、数组的类型),则程序代码就可以处理所有 Animal 的子类。这意味 着其它人只要注意到要扩充过

31、Animal 就可以利用你的 Vet!(P168) 如果此例不用多态,那么每一种动物都要写出不同的方法-这是何等悲哀! (2)接口: 多态意味着“很多形式” ,可以把儿子当作爸爸或爷爷! 可以通过继承来定义相关类间的共同协议(方法就是协议的标志!),这样就等同于在对其他程序代码声明:“我所有的子类都能肠系用这些方法来执行这几项工作!” 为了避免出现“致命方块” 所以 java 不允许出现多继承,接口正是我们的救星!java 接口是 100% 的纯抽象类。而且使用接口可以继承一个以上的来源,同时其他类也可以实现同一个接口中。所以可以为不同的需求组合出不同的继承层次! 三。如何判断应该是设计类、子

32、类、抽象类或接口呢? (1)如果新类无法对其他的类通过 IS-A 测试时,就设计不继承其他类的类。 (2)只有在需要某类的特殊化版本时,以覆盖或增加新的方法来继承现有的类。 (3)当你需要定义一群子类的模板,又不想让其他人初始化此模版时,设计出抽象的类给他们用。 (4)如果想要只定义出类可以扮演的角色,使用接口。 说那么多 自己 经常用用就知道了封装,继承,多态 封装 就是 把 孩子放到一块管理 继承 就是 生孩子 多态 男人 ,女人 ,人妖 ,就是 人的多态你认为大家不理解吗?这些东西,只有用了先知道。 多态,你写过名称相同,参数不同的函数吗? 继承,你的所有 aspx 页面,不都是继承 P

33、age 吗? 封装,你没有自己写过类吗?你类里没有封装方法吗?接口主要涉及跨平台、跨语言、移植性要求较高的编程 一般情况下不会用到的面向对象的三个特征.继承, 封装和多态. C#是一种现代的面向对象的语言. 继承(inheritance):继承是一个面向对象的词语. 说明,一个类( 派生类)能分享,其它类(基类)的特征和行为.派 生类和基类是“is a“的关系. base classes(基类):通常基类可以自己实例化 ,或被继承. 派生类继承基类中的成员,被标记为 protected 或更大 的权限.语法: class (derive class name):(base class name

34、) 例子: /基类 public class Contact /默认私有的字段 string name; string email; string address; /构造函数 public Contact() / statements . /属性 public string Name get return name; set name = value; public string Email get return email; set email = value; public string Address get return address; set address = value; /

35、派生类 public class Customer : Contact /自己的私有字段 string gender; decimal income; public Customer() / statements . 在上面的例子中,Customer 是 Contact 的子类,不但,继承了父类的成员,name,email,address;还有自己的成员,gender,income. abstract classes(抽象类):抽象类是一种特殊的基类 .除过普通的类成员,它们还有抽象的类成员.抽象类成员, 是不能被实例化的方法和属性.所有直接从抽象类派生的类,必须实现抽象的方法和属性.抽象类不

36、能被实例化. 例子: /抽象类 abstract public class Contact protected string name; public Contact() / statements. /抽象方法 public abstract void generateReport(); /抽象属性 abstract public string Name get; set; public class Customer : Contact string gender; decimal income; int numberOfVisits; public Customer() / statements public override void generateReport() / unique report public override string Name get numberOfVisits+; return name; set name = value; numberOfVisits = 0; public class SiteOwner : Contact

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

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报