访问控制、继承、多态.ppt_第1页
访问控制、继承、多态.ppt_第2页
访问控制、继承、多态.ppt_第3页
访问控制、继承、多态.ppt_第4页
访问控制、继承、多态.ppt_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章 访问控制、多态、继承、包和接口,一.访问控制 二.重载 三. 继承 四.多态 五.包和接口,(一)访问控制类的访问控制,同一个java程序文件中的所有类都在同一个包内 多个java文件若声明在同一个pakage下也属于同一个包 处于同一个包内的类是彼此可见的(即可以直接互相调用的),而不同包之间的类,一般是不可见的,只有声明为public的类才可以被访问和调用。,类1,类2,类3,类4是类1的子类,包1,包2,(一)类的访问控制,/ Chp5.java package acl; import java.lang.*; class Area public double lon,wid; public double area(double x,double y) lon=x; wid=y; return x*y; class Test void fun() Chp5 cc=new Chp5(); Area aa=new Area(); public class Chp5 public static void main(String args) Area ss=new Area(); double z=ss.area(1,2); ,Chp5.java, C3.java位于同一个工程下面,但不属于一个包,/C3.java import acl.*; public class C3 Chp5 ss5; /Area ss; /acl.Area类不是public的,无法从外部包对其访问 ,1.缺省类访问控制只能被同一个包内的类所使用 如Area 2.Public类:公共类,可以在任何其它类中( 无论是否在同一个包)使用,如Chp5 3.但如是不在同一个包,要import该包或类 Java规定,一个java文件中有且仅有一个与java文件名同名的public类,(二)成员的访问控制,问题: 某类对其它类整体是可见的 如某类默认的访问控制对同一包内的类 或public类被其它包内的类访问 该类所有数据成员和成员方法也都可见了么? 还取决与该类的成员的修饰符 成员的最终访问控制=类的可见性 +成员的可见性 成员的访问控制 public 公有的 private 私有的 protected 保护的,(1)public 访问控制,只有public类的public数据成员/方法才是任何类都可以访问的 建议:若希望某个类作为公共工具供其它的类和程序使用,应把该类和类内的某个方法声明为public public 类+ public方法 package java.lang; public final class String public String() public Stirng toUpperCase() ,/ Chp5.java package acl; import java.lang.*; class Area public double lon,wid; public double area(double x,double y) lon=x; wid=y; return x*y; class Test void fun() Chp5 cc=new Chp5(); Area aa=new Area(); public class Chp5 public static void main(String args) Area ss=new Area(); /私有类ss可以被同一包中的其它类使用 double z=ss.area(1,2); ,private double lon,wid;,/System.out.print(“ss.lon“+ss.lon);/错!若lon为私有的,类外不能访问,(2)private访问控制,private的数据成员和方法只能被该类自身访问和修改, 不能被其它类和子类所访问,class P1 private int n=9; /私有数据成员n int nn; /默认数据成员 P1( ) nn=n+; /可以被该类的对象自身访问和修改 void ma( ) System.out.println(“n=”+n); / 可以被该类的对象自身访问 public class c5_3 extends P1 public static void main(String args) P1 m1=new P1( ); m1.ma( ); /对!可引用P1类自身的成员方法 System.out.println(“m1.nn=“+m1.nn); /System.out.println(“m1.n=“+m1.n); /错,不能引用父类的私有成员 ,c5_3.java 用private修饰的数据成员不能被子类访问,(3)protected访问控制,(3)protected访问控制 主要用于继承,特别是允许其它的子类可以访问父类的时候 Protected可以被三种类引用: 该类自身同private类外对象不能 同一个包内的其它类 其它包内的该类的子类,/ Chp5.java package acl; import java.lang.*; class Area private double lon,wid; public double area(double x,double y) lon=x; wid=y; return x*y; class Test void funTest() Chp5 cc=new Chp5(); Area aa=new Area(); public class Chp5 public static void main(String args) Area ss=new Area(); double z=ss.area(1,2); Test t=new Test(); t.funTest(); ,以下Chp5.java, C3.java两个文件位于同一个工程下面,但不属于一个包,protectd 例子,protected void fun() ,cc. fun(),/C3.java import acl.Chp5; public class C3 Chp5 ss5; /Area ss;/acl.Area类不是public的 void funTest() ss5=new Chp5(); /ss5.fun(); /C3不是Chp5子类,无权访问fun() class c4 extends Chp5 void funTest() fun(); /C4是Chp5的子类可直接访问父类的fun(), ,二 .方法的重载,问题的引出: 2个int的数相加 add(int,int) 2个double数相加 addDouble(double double) 3个int的数相加 add3(int, int,int) 能不能聪明些呢? 重载: 多个同名的方法,参数个数和类型不同 编译器根据方法调用时候实际参数的个数和类型,选择所对应的重载方法,import java.awt.*; import java.applet.*; public class c5_5 extends Applet int add(int a,int b) /重载的方法1 return(a+b); double add(double x,double y) /重载的方法2 return(x+y); double add(double x,double y, double z) /重载的方法3 return(x+y+z); public void paint(Graphics g) g.drawString(“Sum is:“+add(8.5,2.3),5,10); g.drawString(“Sum is:“+add(21,38),5,30); g.drawString(“Sum is:“+add(8.5,2.3,8.5+2.3),5,50); ,重载例c5_5.java,运行结果如下: Sum is: 10.8 Sum is: 59 Sum is: 21.6,延伸思考:复数的加法呢?,父类 子类,三. 继承,继承: 同类事物具有共性抽取其共性一般类 每个事物又具有特殊性 特殊类 特点 B具有父类A除private外全部属性和方法, 又具有自己的属性和方法 优点 拿来主义,复用 特殊类中不用再重复定义一般类中已经定义好的东西,父类、 基类、 超类、 一般类,子类、 派生类、 特殊类,(二)继承的特征,继承关系是传递的 清晰地体现相关类之间的层次 提供了复用 Java不支持多继承,多继承是由接口实现的 单继承:只有一个父类 多继承:超过两个父类,教师,extends表面继承关系,class A class B extends A 子类可以从父类那里继承所有非private的属性和方法 若一个类没有显式定义父类缺省是系统object的子类,(1)成员的继承(子类继承父类、并可以访问非private数据、方法) c5_6.java,class A1 int x=25; private int z; /不能被子类继承的私有数据成员z class c5_6 extends A1 public static void main(String argS) c5_6 p=new c5_6( ); /创建了子类的对象 System.out.println(“p.x=“+p.x); /继承的数据成员 /System.out.println(“p.z=“+p.z); / 错,不能继承private修饰的z ,p.test(30) void test(int x1) x=x1; System.out.println(“x=“+x); ,p.x=25 x=30,public void setz(int z1)z=z1; /私有变量的存取方法 public getz()return z;,setz(x1+10); /继承来的方法 System.out.println(“A1:z=“+getz();,A1:z=40,例:c5_8.java,子类可以继承父类的非私有成员方法,class A1 int x=0,y=1; void Myp( ) System.out.println(“x=“+x+“ y=“+y); private void Printme( ) System.out.println(“x=“+x+“ y=“+y); public class c5_8 extends A1 public static void main(String arg ) int z=3; c5_8 p1=new c5_8( ); p1.Myp( ); / p1.Printme( ); 错,不能继承父类的private方法 ,/*运行结果: x=0 y=1,(2)成员的隐藏与覆盖,数据成员的隐藏(hidding) 子类的成员变量与父类的成员变量同名时,该父类的成员变量被隐藏 例 成员方法的覆盖(override) 子类覆盖父类方法时,应与父类 同方法名、同返回值类型、和同参 否则成了重载! 二者注意: 数据隐藏: 子类隐藏父类的同名数据成员,而其它父类同名的数据成员在子类对象中仍占有自己独立的内存空间 方法覆盖: 父类方法在子类对象中不复存在,其空间被子类覆盖方法所占用,class Person protected String name; protected int age; protected String address; public void setPerson(String na,int ag,String ad) name=na; age=ag; address=ad; class Student extends Person String address; /子类定义同名数据变量 String sno; String department; public void setStudent(String na,int ag,String ad,String ad1,String no,String de) setPerson(na,ag,ad); /调用父类的方法设置基本信息 address=ad1; /此address为子类的 sno=no; department=de; public class Student_ex public static void main(String args) Person pe=new Person(); Student st=new Student(); pe.setPerson(“Tom“,20,“121_North“); st.setStudent(“John“,19,“121_North“,“234_South_street“,“200601“,“computer“); System.out.println(“Person:”++“ ”+pe.age+“ ”+pe.address); /父类的address System.out.println(“Student:”++“ ”+st.age+“ ”+st.address+“ ”+st.sno+“ ”+st.department); /继承父类的name,age,子类重新定义的address ,a)数据成员的隐藏,Person:Tom 20 121_North Student:John 19 234_South_street 200601 computer,class Person protected String name; protected int age; protected String address; public void setPerson(String na,int ag,String ad) name=na; age=ag; address=ad; public void disp()System.out.println(“Person:“+name+“ “+age); class Student extends Person String address; String sno; String department; public void setStudent(String na,int ag,String ad,String ad1,String no,String de) setPerson(na,ag,ad); /调用父类的方法设置基本信息 address=ad1 sno=no; department=de; public void disp()System.out.println(“Student:“+name+“ “+age+ “ “+address+“ “+sno +“ “+department); /对父类方法的覆盖 public class Student_ex public static void main(String args) Person pe=new Person(); Student st=new Student(); pe.setPerson(“Tom“,20,“121_North“); st.setStudent(“John“,19,“121_North“,“234_South_street“,“200601“,“computer“); pe.disp(); st.disp(); ,b)成员方法的覆盖,Person:Tom 20 Student:John 19 234_South_street 200601 computer,public void disp()System.out.println(“Person:“+name+“ “+age);,public void disp()System.out.println(“Student:“+name+“ “+age+ “ “+address+“ “+sno +“ “+department);,pe.disp(); st.disp();,(3)this 与super,this:当前对象的引用 背景:成员方法的形参或局部变量与数据成员同名时 class Circle double r; public Circle(double r) r= r; ,这个r究竟是哪个r?,this.r,建议:若一个类有多个构造方法,尽可能使用this(参数表)的方式来实现他们 class Circle double r; public Circle(double r) /类的构造方法 this.r=r; public Circle() this(1.0); /用this调用同类其它的构造方法 一般:无参或者参数少的构造方法可以调用参数多的构造方法简化代码 Java要求:this(参数表)应该是构造方法体的第一句,/P105例c5_12.java 计算圆的面积和周长。 class Circle double r; /定义半径 final double PI=3 /定义圆周率 public Circle(double r) /类的构造方法 this.r=r; double area( ) return PI*r*r; /计算圆面积 double perimeter( ) return 2*(this.area( )/r); /计算圆周长 public class c5_12 public static void main(String args) double x; Circle cir=new Circle(5.0); x=cir.area( ); System.out.println(“圆的面积=“+x); x=cir.perimeter( ); System.out.println(“圆的周长=“+x); ,void printMe() System.out.println(“I am an “+this.getClass().getName(); /获得本类的名字Circle,cir.printMe();,圆的面积=78.53981633974999 圆的周长=31.415926535899995 I am an Circle,this 例,public Circle() this(1.0); /用this调用同类其它的构造方法 ,/例 P107 c5_14.java class Addclass public int x=0,y=0,z=0; Addclass(int x) this.x=x; Addclass(int x,int y) this(x); / 当前构造方法调用可重载的构造方法1 this.y=y; Addclass(int x,int y,int z) this(x,y); this.z=z; public int add( ) return x+y+z; public class c5_14 public static void main(String args) Addclass p1=new Addclass(2,3,5); Addclass p2=new Addclass(10,20); Addclass p3=new Addclass(1); System.out.println(“x+y+z=“+p1.add( ); System.out.println(“x+y=“+p2.add( ); System.out.println(“x=“+p3.add( ); ,this必须是方法体的第一句!,使用this调用重载的构造方法,super对当前对象的直接父类对象的引用,父类有disp方法,子类也有disp, 例 为了省点代码,能否先调用父类中被覆盖的方法? super 例 Super使用的场合: 访问直接父类中隐藏的数据成员 super.数据成员 调用直接父类中被覆盖的成员方法 super.方法(参数) 调用直接父类中被覆盖的构造方法 放在构造方法中 super(参数),class Person protected String name; protected int age; public Person(); public Person(String na,int ag) name=na; age=ag; public void setPerson(String na,int ag) name=na; age=ag; public void disp() System.out.print(name+“ “+age+“ “); class Student extends Person String sno; String dept; public void setStudent(String na,int ag,String no,String de) setPerson(na,ag); /直接使用继承下来的父类的方法 sno=no; dept=de; public void disp() System.out.println(name+“ “+age+“ “+sno+“ “+dept); ,super例,super.disp(); /调用父类被覆盖的方法 System.out.println(sno+“ “+dept);,运行结果: cq 18 2006010 计算机系,public class Student_ex public static void main(String args) Person p1=new Person(); Student s1=new Student(); s1.setStudent(“cq“,18,“2006010“,“计算机系“); s1.disp(); ,Student s2=new Student(“zhang“,19, “2006020“,“自动化系“); s2.disp();,public Student(String na,int ag,String no,String de) super(na,ag); /调用父类的构造方法 sno=no; dept=de; public Student(),super必须是方法体的第一句!,运行结果: cq 18 2006010 计算机系 Zhang 19 2006020 自动化系,返回,(4)构造方法的继承,1.子类无条件继承父类的无参构造 class A int aa; class B extends A int bb; public static void main(String args) ,2.若子类自己定义构造方法,先缺省调用父类的无参构造,再执行自己的构造方法体 class A int aa; public A()System.out.println(“A:con“); class B extends A int bb; public B()System.out.println(“B:con“); public static void main(String args) B test=new B(); /* A:con B:con */,/【示例程序c5_15.java】 class addclass public int x=0,y=0,z=0; addclass(int x) this.x=x; /父类可重载的构造方法1 addclass(int x,int y) this.x=x; this.y=y; /父类可重载的构造方法2 addclass(int x,int y,int z) this.x=x; this.y=y; this.z=z; /构造3 public int add( ) return x+y+z; public class c5_15 extends addclass int a=0,b=0,c=0; c5_15(int x) /子类可重载的构造方法1 super(x); a=x+7; c5_15(int x,int y) super(x,y); a=x+5; b=y+5; c5_15(int x,int y,int z) super(x,y,z); a=x+4; b=y+4; c=z+4; public int add( ) System.out.println(“super: x+y+z=“+super.add( ); return a+b+c; ,public static void main(String args) c5_15 p1=new c5_15(2,3,5); c5_15 p2=new c5_15(10,20); c5_15 p3=new c5_15(1); System.out.println(“a+b+c=“+p1.add( ); System.out.println(“a+b=“+p2.add( ); System.out.println(“a=“+p3.add( ); ,3.若子类想调用父类的带参构造,应使用super,再执行自己的构造方法体,运行结果如下: super: x+y+z=10 a+b+c=22 super: x+y+z=30 a+b=40 super: x+y+z=1 a=8,(5)向方法传递对象,方法的参数 是简单变量值传递对形参的修改不影响实参 是对象双向地址传递对形参的修改影响实参,/【示例程序c5_16.java】 import java.awt.*; import java.applet.*; class student public String Name; public int age=16; public int score=0; public void ShowStudent(Graphics g,int x,int y) g.drawString(“Name:“+Name,x,y); g.drawString(“age:“+age,x,y+20); g.drawString(“score:“+score,x,y+40); ,public class c5_16 extends Applet public void studentAttributes(student s,String Name, int age, int score) s.Name=Name; s.age=age; s.score=score; public void paint(Graphics g) student st1=new student( ); /创建对象st1 student st2=new student( ); /创建对象st2 studentAttributes(st1,“zhang“,23,81); /对象st1作为实参 studentAttributes(st2,“li“,24,90); /对象st2作为实参 st1.ShowStudent(g,25,25); /执行此方法可发现对象st1将新值带回 st2.ShowStudent(g,25,120); /再次执行此方法可发现对象st2将新值带回 ,五 抽象类和接口,二维图形的绘制 可以分别写三个类,但都用到了原点,getArea(),getPerimeter() 为什么不抽取共性,形成父类呢Shape类 但Shape是一个笼统的的二维图形,具体究竟是什么图形呢? 抽象类 abstract class Shapes ./定义一个抽象类Shapes,r,width,height,width,height,(x,y),(x,y),(x,y),抽象方法,抽象类,(一)抽象类,抽象类和抽象方法的定义,抽象类 abstract class Shapes ./定义一个抽象类Shapes 描述了共有的行为,并通过继承传递给子类 抽象类不能实例化即不能创建对象 抽象方法 在抽象类中定义的方法,只有方法的声明,没有方法体 它的具体实现是由子类重新定义并实现的 abstract double getArea( ); /求图形面积的抽象方法,示例程序c5_18.java】 抽象类应用。 import java.awt.*; import java.applet. *; abstract class Shapes /定义一个抽象类Shapes public int x,y; /x、y为画图的坐标 public int width,height; public Shapes(int x,int y,int width,int height) this.x=x; this.y=y; this.width=width; this.height=height; abstract double getArea( ); /求图形面积的抽象方法 abstract double getPerimeter( ); /求图形周长的抽象方法 class Square extends Shapes /由抽象类Shapes派生的子类矩形类 public double getArea( )return(width*height); public double getPerimeter( )return(2*width+2*height); public Square(int x,int y,int width,int height) super(x,y,width,height); ,class Triangle extends Shapes public double c; /斜边 public double getArea( )return(0.5*width*height); public double getPerimeter( )return(width+height+c); public Triangle(int x,int y,int width,int height) /更改书上的 super(x,y, width,height); c=Math.sqrt(width*width+height*height); class Circle extends Shapes public double r; /半径 public double getArea( )return(r*r*Math.PI); public double getPerimeter( )return(2*Math.PI*r); public Circle(int x,int y,int width,int height) /widthheigh作为直径 super(x,y,width,height); r=(double)width/2.0; ,public class c5_18 extends Applet Square Box=new Square(5,15,25,25); Triangle tri=new Triangle(5,50,8,4); Circle Oval=new Circle(5,90,25,25); public void paint(Graphics g) g.drawRect(Box.x,Box.y,Box.width,Box.height); /java提供的画矩形方法 g.drawString(“Box Area:“+Box.getArea( ),50,35); g.drawString(“Box Perimeter:“+Box.getPerimeter( ),50,55); g.drawString(“tri Area:“+tri.getArea( ),50,75); g.drawString(“tri Perimeter:“+tri.getPerimeter( ),50,95); g.drawOval(Oval.x,Oval.y,Oval.width,Oval.height); / /java提供的画圆 g.drawString(“oval Area:“+Oval.getArea( ),50,115); ,public class c5_17 extends Applet public void paint(Graphics g) Shapes s=new Shapes3; /声明对象数组时,不为每个对象 分配空间,即只是创建了三个 shape的引用 s0=new Square(5,15,25,25); /这才真正的创建对象 s1=new Triangle(5,50,8,4); s2=new Circle(5,90,25,25); for(int i=0;i3;i+) g.drawString(si.getClass().getName(),25,25+i*100); g.drawString(“ “+si.getArea(),25,50+i*100); g.drawString(“ “+si.getPerimeter(),25,75+i*100); ,补充更改,(二)接口,接口名,抽象方法:吃法说明,常量,interface Eatable final String TASTY=“好吃有味“; final String TASTYLESS=“没有味道“; abstract void howtoEat(); class Apple implements Eatable String name; public Apple(String name) =name; public void howtoEat() System.out.println(“削皮吃 “+name+“ “+TASTY); class Chicken implements Eatable public void howtoEat() System.out.println(“烤熟吃 “+this.getClass().getName()+“ “+TASTY); class Paper implements Eatable public void howtoEat() System.out.println(“撕着吃 “+this.getClass().getName()+“ “+TASTYLESS); public class TestEatable public static void main(String args) Eatable eats=new Apple(“红苹果“),new Chicken(),new Paper(); for(int i=0;i3;i+) eatsi.howtoEat(); ,削皮吃 红苹果 好吃有味 烤熟吃 Chicken 好吃有味 撕着吃 Paper 没有味道,用接口实现多继承,interface A public void mA(); interface B public void mB(); class RAB implements A,B public void mA() System.out.println(“implement mA“); public void mB() System.out.println(“implement mB“); public class TestEatable public static void main(String args) RAB rab=new RAB(); rab.mA(); rab.mB(); ,implement mA implement mB,修改c_17改抽象类 为接口C5_19,import java.awt.*; import java.applet. *; interface Shapes /定义一个接口Shapes abstract double getArea( ); /求图形面积的抽象方法 abstract double getPerimeter( ); /求图形周长抽象方法 class Coordinates int x,y; public Coordinates(int x,int y) this.x=x; this.y=y; ,class Square extends Coordinates implements Shapes public int width,height; public double getArea( )return(width*height); public double getPerimeter( )return(2*width+2*height); public Square(int x,int y,int width,int height) super(x,y); this.width=width; this.height=height; ,class Triangle extends Coordinates implements Shapes public int width,height; public double c; /斜边 public double getArea( )return(0.5*width*height); public double getPerimeter( )return(width+height+c); public Triangle(int x,int y,int base,int height) super(x,y); width=base; this.height=height; c=Math.sqrt(width*width+height*height); ,class Circle extends Coordinates implements Shapes public double r; /半径 public double getArea( )return(r*r*Math.PI); public double getPerimeter( )return(2*Math.PI*r); public Circle(int x,int y,double r) super(x,y); this.r=r; ,public class c5_19 extends Applet Square Box=new Square(5,15,25,25); Triangle tri=new Triangle(5,50,8,4); Circle Oval=new Circle(5,90,12.5); public void paint(Graphics g) g.drawRect(Box.x,Box.y,Box.width,Box.height); g.drawString(“Box Area:“+Box.getArea( ),50,35); g.drawString(“Box Perimeter:“+Box.getPerimeter( ),50,55); g.drawString(“tri Area:“+tri.getArea( ),50,75); g.drawString(“tri Perimeter:“+tri.getPerimeter( ),50,95); g.drawOval(Oval.x,Oval.y,Oval.width,Oval.height); /画圆 g.drawString(“oval Area:“+Oval.getArea( ),50,115); ,包,假设当前工作目录为D:cq1Myjava,/Shapes.java package shape; import java.awt.*; import java.applet. *; public interface Shapes /定义一个接口Shapes abstract double getArea( ); /求图形面积的抽象方法 abstract double getPerimeter( ); /求图形周长抽象方法 class Coordinates int x,y; public Coordinates(int x,int y) this.x=x; this.y=y; ,/Square.java package shape; public class Square extends Coordinates implements Shapes public int width,height; public double getArea( )return(width*height); pub

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论