




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
继承与多态继承--构造方法在类继承中的作用多态性方法的重载、方法的覆盖几个特殊类Object类、Class类访问控制修饰符final修饰符的使用对象引用转换赋值转换、强制转换继承的概念父类或超类。实际上是所有子类的公共域和公共方法的集合子类,父类的特殊化,是对公共域和方法在功能、内涵方面的扩展和延伸,祖先类的所有成员均将成为子类拥有的“财富”Object类是所有类的祖先什么叫继承
继承是类与类之间的一种关系。如果某个子类继承于某个父类。则子类拥有父类的所有公有(public)属性和公有方法。同时,子类也可以拥有自己独自的属性和方法。继承(Inherit)学生是扩充了人的概念,人(Person)和学生(Studnet)类中有大量的代码是重复的Student应该想办法去重用Person类,即在Person类的基础上进行扩展,即子类扩展父类已有的功能,同时可以将父类中的操作全部继承下来。(只允许单继承,不允许多继承,即一个子类只有一个父类,一个父类可以有多个子类)父类在JAVA中也称为超类。父类所有的公有成员和公有方法:父类中的公有属性和公有方法父类中的私有属性和私有方法子类中的属性和方法子类可以继承父类一切非私有的方法和属性,但对于私有的方法和属性需要采用间接的手段才可以使用。继承(Inherit)继承的语法规则class子类名extends父类名{
任意语句;}Java继承的实现importjava.awt.Color;classPixel{
privateintx;//x坐标privateinty;//y坐标
Colorc;//颜色
//其他……}x,y在Point类中有定义Java继承的实现importjava.awt.Color;classPixelextendsPoint{
Colorc;//颜色
//其他……}只有c属性是新加入的,其它属性在Point类中均存在
继承关系中构造方法的作用(1)子类可以在自己构造方法中使用关键字super来调用父类的构造方法,但super调用语句必须是子类构造方法中的第一个可执行语句;(2)子类在自己定义构造方法中如果没有用super明确调用父类的构造方法,则在创建对象时,首先自动执行父类的无参构造方法即子类中的构造方法中第一句代码隐含super();//调用父类中的无参构造方法。,然后再执行自己定义的构造方法。
构造子类对象时会先构造父类对象!必须是子类构造方法的第1条语句!构造方法不能继承。在创建子类的对象(即对象实例化)时,除了要执行子类的构造方法外,还需要调用父类的构造方法。具体遵循原则如下:继承关系中构造方法的作用父类对象必须实例化之后,调用父类中的构造方法为其开辟空间,同时为类中的属性初始化。才能产生子类。Java继承的实现classPerson{privateStringusername;privateintuserage;publicvoid
setName(Stringname){this.username=name;}publicStringgetName(){returnthis.username;}publicvoid
setAge(intage){this.userage=age;}publicintgetAge(){returnthis.userage;}Person(){System.out.println("无参构造方法");}Person(Stringname,intage){if(age>0&&age<150){username=name;userage=age;}else{this.username=name;this.userage=-1;}}publicStringtoString(){return"说话的人姓名:"+username+",年龄:"+userage;}};Java继承的实现classStudentextendsPerson{privateStringschool;Student(Stringname,intage,Stringschool){this.setName(name);this.setAge(age);//this都可以省略this.school=school;}//这个this不可省略publicStringtoString(){return"说话的人姓名:"+this.getName()+",年龄:"+this.getAge()+",学校:"+this.school;}};publicclassjcheng{publicstaticvoidmain(Stringargs[]){Students1=newStudent("张三",20,"浙大");System.out.println("s1"+s1.toString());}//toString()可以省略//,如果不是toString()方法而是改成其它名称的方法,就不可以省略}super()无参、带参使用和super的使用classPerson{privateStringusername;privateintuserage;//Person(){System.out.println("无参构造方法");}Person(Stringname,intage){if(age>0&&age<150){username=name;userage=age;}else{this.username=name;this.userage=-1;}}publicStringtoString(){return"说话的人姓名:"+username+",年龄:"+userage;}};super()无参、带参使用和super的使用classStudentextendsPerson{privateStringschool;//Student(){super();}//默认调用父类中的无参构造方法,可省略Student(Stringname,intage,Stringschool){
super(name,age);//调用父类中的带2个参数的构造方法this.school=school;}publicStringtoString(){returnsuper.toString()+",学校:"+this.school;}/*调用父类中的toString()方法*/};publicclassjcheng{publicstaticvoidmain(Stringargs[]){//Students1=newStudent();//调用无参构造方法Students1=newStudent("张三",20,"浙大");System.out.println("s1"+s1.toString());}}重载与覆写重点:重载与覆写的区别:覆写:
方法名称完全一样,参数也要一样,在覆写之后子类调用的永远是覆写之后的方法。
覆写时子类方法的权限不能比父类拥有更严格的访问权限,覆写之后的权限最好与父类中保持一致(不是绝对,如果父类中的权限是public则最好保持一致)重载覆写概念方法名称相同,参数的类型或个数不同方法名称、访问权限【最好】、参数的类型个数一样范围是发生在同一个类是发生在继承关系中,子类实现的三种权限:public(公有):权限最大,任何人都可以访问default(默认):仅次于public权限private(私有):权限最小,只能在一个类中访问如果在父类中方法的访问权限是private,你们此方法能否被覆写?This与super的区别super关键字:在子类对象实例化时在子类的构造方法中,默认隐含了一个super()的代码,调用父类【超类】中的特定构造方法。可以通过super(),括号里面根据传入的参数去调用父类中指定的构造方法,默认情况下调用的是无参构造方法。通过super()方法,可以由子类去调用父类中指定的方法(方法被覆写了)super.方法():调用父类中被覆盖的方法扩展(了解):属性也是可以被覆写This与super的区别This与super的区别:使用上很相似,都可以调用其他方法,其他属性,构造方法,【都必须放在首行】,可见他们不能在同一个构造方法在出现,this调用构造肯定要留有一个出口。类型包装类使用范围调用本类中的方法或属性从子类中调用父类中的方法或属性调用属性This本类属性,从本类中查找Super父类属性,从父类中查找调用方法This本类方法(),从本类中查找Super父类方法(),从父类中查找调用构造放在本类构造方法的首行,构造方法需要有一个出口(至少有一个构造方法没有用this调用)放在子类构造方法之中,默认情况下子类隐藏一个super(),去调用父类中默认的构造方法特殊点This表示当前对象无以下程序在编译时将出错,为什么?classparent{Stringmy;publicparent(Stringx){my=x;}}publicclasssubclassextendsparent{}parent类没有无参构造方法。所以,类设计通常要提供无参构造方法【例】类的继承中构造方法的调用测试importjava.awt.Color;classPoint{privateintx,y;publicPoint(intx,inty){//有参构造方法
this.x=x;this.y=y;}publicPoint(){//无参构造方法
this(0,0);
//用this调用本类的另一构造方法}publicStringtoString(){
return"点:"+x+","+y;;}}this代表当前对象【例】续publicclassPixelextendsPoint{Colorc;publicPixel(intx,inty,Colorc){super(x,y);//用super调用父类的构造方法
this.c=c;}publicStringtoString(){
returnsuper.toString()+“颜色:”+c;
}publicstaticvoidmain(Stringa[]){Pixelx=newPixel(3,24,Color.blue);
System.out.println(x);}}【注意】使用this查找匹配的方法时首先在本类查找,找不到时再到其父类和祖先类查找;使用
super
查找匹配方法时,首先到直接父类查找,如果不存在,则继续到其祖先类逐级往高层查找。没有这行,执行super()用super调用父类成员多态性——是面向对象语言中最重要多态性体现在以下两个方面方法的重载(overload):是指在同一个类中定义多个方法名相同,但参数个数和类型不同的方法。子类对父类方法的覆盖(override):在子类中对父类定义的方法重新定义后,这样在子类中将覆盖来自父类的同形态方法。方法的重载publicclassA{
voidtest(intx)
{
System.out.println("test(int):"+x);}
voidtest(longx)
{
System.out.println("test(long):"+x);}
voidtest(doublex)
{System.out.println("test(double):"+x);}publicstaticvoidmain(String[]args){
Aa1=newA();
a1.test(5.0);
a1.test(5);}}多态性运行结果如下test(double):5.0test(int):5首先按“精确匹配”原则去查找匹配方法,如果找不到,则按“自动类型转换匹配”原则去查找能匹配的方法。所谓“精确匹配”就是实参和形参类型完全一致。所谓“自动转换匹配”是指虽然实参和形参类型不同,但能将实参的数据按自动转换原则赋值给形参。方法调用的匹配处理原则publicclassA{
//voidtest(intx){
System.out.println("test(int):"+x);}
voidtest(longx){System.out.println("test(long):"+x);}
voidtest(doublex){
System.out.println("test(double):"+x);}
publicstaticvoidmain(String[]args){
Aa1=newA();
a1.test(5.0);
a1.test(5);
}
}【思考】如果将test(intx)方法注释掉,则调用test(5)如何?以上3个方法中,如果只将test(doublex)方法注释掉,程序能编译通过吗?
例
复数的加法publicclassComplex{privatedoublex,y;//x,y分别代表复数的实部和虚部
publicComplex(doublereal,doubleimaginary){x=real;y=imaginary;}publicStringtoString(){return"("+x+","+y+"i"+")";}/*方法1:将复数与另一复数a相加*/publicComplexadd(Complexa){//实例方法
returnnewComplex(x+a.x,y+a.y);}/*方法2:将复数与另一个由两实数a,b构成的复数相加*/publicComplexadd(doublea,doubleb){//实例方法
returnnewComplex(x+a,y+b);}/*方法3:将两复数a和b相加*/publicstaticComplexadd(Complexa,Complexb){//静态方法
returnnewComplex(a.x+b.x,a.y+b.y);}思考实例方法和静态方法的差异性!静态方法和实例方法的区别主要体现在两个方面:
在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法,静态方法中也不能使用关键字this;实例方法则无此限制。
publicstaticvoidmain(Stringargs[]){Complexx,y,z;x=newComplex(4,5);y=newComplex(3.4,2.8);z=add(x,y);//调用方法3进行两复数相加
System.out.println("result1="+z);z=x.add(y);//调用方法1进行两复数相加
System.out.println("result2="+z);z=y.add(4,5);//调用方法2进行两复数相加
System.out.println("result3="+z);}}方法的覆盖以下类B定义的方法中,方法覆盖如何?classBextendsA{
voidtest(intx){
System.out.println("inB.test(int):"+x);
}voidtest(Stringx,inty){
System.out.println("inB.test(String,int):"+x+","+y);
}
}【思考】通过子类B的对象可调用多少test方法?publicclassA{
voidtest(intx)…
voidtest(longx)…
voidtest(doublex)…}关于方法覆盖有以下问题值得注意:
方法名、参数列表、完全相同才会产生方法覆盖;返回类型通常也要一致,只有返回类型为引用类型时,允许子类方法的返回类型是父类方法返回类型的子类型。其他情形导致类型不一致时编译将指示错误。覆盖不能改变方法的静态与非静态属性。子类中不能将父类非静态方法定义为静态方法,反之也一样。不允许子类方法的访问修饰符比父类有更多的限制。
例如:子类不能将父类的public方法定义为protected方法。但可以将父类的private方法在子类中重新定义为public方法.final方法不能被覆盖。访问继承的成员实例方法根据变量所引用对象的实际类型进行访问;属性和静态方法根据引用变量的类型进行访问.(1)如果子类中定义了与父类同名的属性,在子类中将隐藏来自父类的同名属性变量。通过子类的引用变量访问对象时无论属性和方法优先考虑子类新定义的。(2)父类引用变量引用子类对象时的成员访问【例】访问继承的成员
classSuperShow{inty=8;//父类SuperShow的y属性
intm=2;
voidshow(){//父类SuperShow的show方法
System.out.println("sup.show,y="+y);
}}publicclassExtendShowextendsSuperShow{inty=20;//子类ExtendShow的y属性
intz=1; voidshow(){//子类B的show方法
System.out.println("ext.show,y="+y);}
每个子类对象有4个属性yzsuper.ympublicstaticvoidmain(Stringargs[]){ExtendShowb=newExtendShow();SuperShowa=b;System.out.println("ext.y="+b.y);System.out.println("sup.y="+a.y);b.show();
a.show();
System.out.println("z="+b.z+",m="+b.m);}}
classSuperShow{inty=8;
intm=2;
voidshow(){
System.out.println("sup.show,y="+y);
}}publicclassExtendShowextendsSuperShow{inty=20;intz=1; voidshow(){
System.out.println("ext.show,y="+y);}
Object类Object类是所有Java类的最终祖先,所有类都必须继承自Object类,它是类之源——是最大的类,是所有类的父类,一切对象都可以向Object类进行转换。以下给出了3个常用方法:publicbooleanequals(Objectobj):该方法本意用于两个对象的“深度”比较,也就是比较两对象封装的数据是否相等;而比较运算符“==”在比较两对象变量时,只有当两个对象引用指向同一对象(即在同一个地址)时才为真值。但在Object类中,equals方法是采用“==”运算进行比较;publicStringtoString():该方法返回对象的字符串描述;publicfinalClassgetClass():返回对象的所属类;protectedvoidfinalize():该方法Java垃圾回收程序在删除对象前自动执行。几个特殊类Object类toString():在对象打印时默认调用,但是默认情况下调用的是Object类中的toString(),如果一个类希望按自己的方式打印对象,则可以通过覆写的方式,将toString()方法覆写。在JAVA中大部分类基本上都是继承关系。例equals方法与“==”的示例publicstaticvoidmain(String[]args){Stringname1="abcd123va";//是类的匿名对象,一个空间Stringname2=newString("abcd123va");//两个空间System.out.println(name1.equals(name2));//trueSystem.out.println(name1==name2);}//false
例
给Point类增加equals方法publicclassPoint{privateintx,
y;publicPoint(intx,inty){this.x=x;this.y=y;
}
publicbooleanequals(Pointp){return(x==p.x&&y==p.y);}publicStringtoString(){return"点:"+x+","+y;}
注意形态,并没覆盖Object类的equals方法!publicstaticvoidmain(Stringarg[]){Pointx=newPoint(4,3);System.out.println("x="+x);System.out.println(x.equals(newPoint(4,3)));
}}【思考】观察有无toString()方法时程序运行结果的变化。观察有无equals(Pointp)方法程序运行结果的变化。
Class类(选讲)1.获取Class类型的对象Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。有以下3种方法可以获取Class的对象。方法1:调用Object类的getClass()方法。方法2:使用Class类的forName()方法。方法3:如果T是一个Java类型,那么T.class就代表了与该类型匹配的Class对象。例如,String.class代表字符串类型,int.class代表整数类型。Class类的常用方法staticClass<?>forName(StringclassName):返回给定串名相应的Class对象。TnewInstance():创建类的一个实例。String
getName():返回Class对象表示的类型(类、接口、数组或基类型)的完整路径名字符串。Method[]
getMethods():返回当前Class对象表示的类或接口的所有公有成员方法对象的数组。进一步利用Method类提供的invoke方法可实现相应类的成员方法的调用。Objectinvoke(Objectobj,Object[]args)其中,obj代表调用该方法的类实例对象,args代表存放方法参数的对象数组。MethodgetMethods(Stringname,Class…parameterType):返回指定方法名和参数类型的方法对象。Field[]
getFields():返回当前Class对象表示的类或接口的所有可访问的公有域对象的数组。【例】反射机制简单测试举例。importjava.lang.reflect.*;classTest{publicintadd(intx,inty){returnx+y;}publicintminus(intx,inty){returnx-y;}}publicclassA{publicstaticvoidmain(String[]args)throwsException{Classmyclass=Class.forName("Test");System.out.println(myclass.getName());Objectx=myclass.newInstance(); //获取Test类的一个对象Method[]m=myclass.getMethods(); //获取Test类的所有方法Object[]Args=newObject[]{1,2};for(inti=0;i<2;i++)System.out.println(m[i].toString());System.out.println(m[0].invoke(x,Args)); //调用对象的第1个方法Methodaddm=myclass.getMethod("add",int.class,int.class);System.out.println(addm.invoke(x,Args));
//调用add方法}}公共访问控制符public应用范围:类、类的成员(字段变量或方法)作为类的修饰符,将类声明为公共类,表明它可以被所有的其它类所访问和引用作为类的成员的访问修饰符,表明在其他类中可以无限制地访问该成员。即可以在其他类中访问public修饰的成员。注意:要真正做到类成员可以在任何地方访问,在进行类设计时必须同时满足两点:首先类被定义为public,其次,类的成员被定义为public。访问控制修饰符缺省访问控制符默认访问控制符指没有在类或者成员前面指明访问控制符的情形。在这种情况下,该成员只能在同一个包的类中访问,不可以在其他包的类中访问。没有给出访问控制符情形该类只能被同一个包中的类访问和引用
私有访问控制符private用private修饰的域或方法表明该成员是类中的私有成员,只能被该类自身所访问,不能在其他类中被访问。子类在继承父类时,也无法继承父类中的private成员。【例】测试对私有成员的访问。classMyclass{
privateinta;//私有变量voiddisplay(){System.out.println(a);}}
publicclasstest{publicstaticvoidmain(Stringarg[]){Myclassmy=newMyclass();
my.a=5;
my.display();}}
保护访问控制符protected用protected修饰的成员可以在三种类中所引用:该类本身;与它在同一个包中的其它类;在其它包中的该类的子类。【例】测试包的访问控制文件1:PackageData.java(该文件存放在sub子目录下)packagesub;
publicclassPackageData{
protectedstaticintnumber=1;
}
文件2:Mytest.javaimportsub.*;
publicclassMytest{
publicstaticvoidmain(Stringargs[]){
System.out.println("result="+PackageData.number);
}}
在同一个包中就是对的,如果在不同包中则文件2类得改成子类各类访问控制符的作用可直接访问修饰同一类中同一包中不同包的子类中其他privateYes
默认YesYes
protectedYesYesYes
publicYesYesYesYes
final修饰符
final的使用范围final作为类修饰符:用final修饰的类称为最终类。
----最终类(不能有子类),即该类不允许被继承。用final修饰方法:称为最终方法。----不能被子类重新定义,即在子类中不能再对父类的final方法重新定义。用final定义常量:也称为常量。
----只能赋值一次,常量可以在定义时赋值,也可以先定义后赋值例:finaldoublex=3.7;//X最好大写注意:如果将引用类型的变量标记为final,那么该变量固定指向一个对象,但可以改变对象内的属性值。注意:所有private方法,以及所有包含在final类中的方法,都被默认为final。例
常量赋值测试publicfinalclassAssignTest{publicstaticinttotalNumber=5;
publicfinalintid;
publicintweight;publicAssignTest(intweight){id=totalNumber++;
this.weight=weight;}publicstaticvoidmain(Stringargs[]){
finalAssignTestt=newAssignTest(5);t.weight=t.weight+2;t=newAssignTest(4);//不允许,t是常量不能重新赋值
t.id++;//不允许}}
与普通属性变量不同的是,系统不会给常量赋默认初值.
对象引用赋值转换允许将子类对象赋值给父类引用。publicclassA{
voidtest(Objectobj){//方法的重载System.out.println("test(Object):"+obj);}voidtest(Stringstr){//方法的重载System.out.println("test(String):"+str);}publicstaticvoidmain(String[]args){Aa1=newA();a1.test("hello");
}}如果将test(Stringstr)方法定义注释掉,则运行结果如何?对象引用强制转换将父类引用赋值给子类变量时要进行强制转换,强制转换在编译时总是认可的,但运行时的情况取决于对象的值。
Objectm=newString("123");//允许,父类变量引用子类对象Stringy=m;//不允许Stringy=(String)m;//强制转换,编译允许,且运行没问题Integerp=(Integer)m;//强制转换,编译允许,但运行时出错问题思考继承意味着什么?什么是变量的隐藏?子类构造方法与父类构造方法有何联系?什么是参数多态性?什么是覆盖多态性?访问控制符有哪些?final修饰符作用于类、方法、属性变量上的含义?super的作用?如何访问父类的方法和构造方法?对象引用转换的特点?写运行结果classexSuper{publicvoidfunc(Stringp,Strings){System.out.println(p);}}publicclassexampleextendsexSuper{publicvoidfunc(Stringp,Strings){System.out.println(p+":"+s);}staticpublicvoidmain(Stringarg[]){exSupere1=newexSuper();e1.func("hello1","hi1");exSupere2=newexample();e2.func("hello2","hi2");}}结果hello1hello2:hi2classTest5{intk=8;public
voiddoSome(){k++;System.out.println("k1="+k);}}classSubextendsTest5{intk=66;public
voiddoSome(){k=k-2;System.out.println("k2="+k);}publicstaticvoidmain(Stringargs[]){Test5obj=newSub();obj.doSome();System.out.println("k3="+obj.k);
}}结果k2=64k3=8写运行结果publicclassIsEqual{
intx;
publicIsEqual(intx1)
{
x=x1;
}
publicstaticvoidmain(Stringa[])
{
IsEqualm1=newIsEqual(4);
IsEqualm2=newIsEqual(4);
IsEqualm3=m2;
m3.x=6;
System.out.println("m1=m2is"+(m1==m2));
System.out.println("m2=m3is"+(m2==m3));
System.out.println("m1.x=
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年计算机基础考试策略分享试题及答案
- 2024年宠物营养师创新成果展示试题及答案
- 自考公共事业管理2024年教材更新试题及答案
- 第1讲 电流 电阻 电功 电功率-2026版大一轮高考物理复习
- 语文知识竞赛试题及答案
- 优化2024年汽车维修工考试备考流程试题及答案
- 二手车相关政策法规试题及答案
- 二手车评估的科技应用趋势试题及答案
- 中高级汽车维修工的职业规划试题及答案
- 早教培训测试题及答案
- 2024年中国资源循环集团有限公司招聘笔试真题
- 危货车辆防汛救援应急预案
- 2025年全国国家版图知识竞赛(中小学组)题库及答案
- 社区商业中心公共设施的规划与运营管理
- 2024年河南省中职英语对口高考试题
- 政治-山东省潍坊市2025届高三2月开年诊断调研监测考试试题和答案
- 课件-DeepSeek从入门到精通
- 公司清明节前安全教育
- 石油开发地质学-第5章-圈闭和油气藏
- 英语语法-时间介词-练习题(带答案)
- 2025年山东出版集团招聘笔试参考题库含答案解析
评论
0/150
提交评论