1、第4讲 Java面向对象程序设计(一),2018/10/17,1,本章内容,4.1 类与对象 4.2 继承与多态 4.3 接口 4.4 包,2,学习目标,掌握对象与类的基本概念 熟练掌握类的定义及实例化 熟练掌握类的继承与多态 熟练掌握接口的定义及实现,3,4.1 类与对象,类: 现实生活中具有共同特性的对象的抽象就称之为类。如:学生 对象: 是用来描述现实世界中实际存在的事物的实体,由一组属性和一组操作构成。对象是其类的实例(一个特例)。如:学生王明 对象的属性表示了它所处于的状态,一个对象具有多个属性。如:学生的姓名、班级、成绩等 对象的操作则是用来改变对象状态达到特定的功能,对象的操作也
2、叫行为或方法。如:计算学生成绩,4,【例4.1】点类Point,5,由“类图”到“Java类”的转换,类图与Java类的对应关系:,6,package ch4; /定义类所属的包 Import java.io.*; /导入外部类 public class Point private int x; private int y;public int getX() return x; / 读xpublic int getY() return y; / 读ypublic void setX(int newX) x = newX; / 写xpublic void setY(int newY) y = n
3、ewY; / 写ydouble distance() return Math.sqrt(x * x + y * y); / 求点到原点的距离 ,类首部,类 体,属性定义,方 法 定 义,7,4.1.1类首部,package ch4; /定义类所属的包 import java.io.*; /导入外部类 public class Point Java类首说明的形式如下:package说明 import 说明访问说明符 class 类名 extends 超类名 implements 接口名列表,/类首部,8,类首部,(1)“package 说明” package pkg1.pkg2.pkg3; 指定
4、程序中的类属于哪个包,包名用“.” 分隔,一般小写 包定义语句在每个源程序中只能有一条,即一个类只能属于一个包; 包定义语句必须在程序的第一行(之前可有空格及注释);如:,9,类首部,(2)“import说明” import PackageName.SystemClassName; 指出要使用的Java系统类或自定义的非本包类; 如:import java.util.Arrays;import ch3.ReadData; eclipse中组织导入:Source/Orgnize Imports命令,10,类首部,系统提供的包和自己定义的包都可以不加import,直接引用。 引用方式:包名.类名.
5、方法名(); 如:System.out.println();如:ch3.ReadData.readChar(); Java自带包: 以“java.”开头; 作为java 的一个标准部分发布API; 学习Java,必须学习Java 常用包中的类。,11,类首部,(3)访问说明符/类的修饰符 friendly:同包内,默认 public:同项目 abstract:抽象类,含有抽象方法(没有方法体的方法) final:不能被继承 一个类可以同时有多个修饰符。 多个修饰符无先后顺序之分。 abstract和final不能同时修饰一个类。,12,package ch4; class A_friendly
6、 package ch4; class B_friendly A_friendly af; /无需import ,13,package ch3; import ch4.A_friendly; /The type ch4.A_friendly is not visible /change visibility of A_friendly to public class B_friendly A_friendly af; /A_friendly cannot be resolved to a type ,14,package ch4; public class A_public int x;int
7、 y; package ch4; class B_friendly A_public ap; /无需import ,15,package ch3; import ch4.A_public; class B_friendly A_public ap; ,16,package ch4; abstract class A_abstract int x;int y;abstract int max(); package ch4; public class AA extends A_abstractOverrideint max() / TODO Auto-generated method stubre
8、turn 0; ,17,package ch4; final class A_final int x;int y; package ch4; public class AAA extends A_final /error:The type AAA cannot subclass the final class A_final ,18,类首部,(4)class 类名 唯一不可缺的一部分; class是类定义保留字。 类名:首字母大写,内部单词的首字母也大写。 如:class Student,19,类首部,(5)extends(继承) extends SuperClassName; 表明这个类继承
9、了哪个类。 继承的父类只能有一个。 如: public class HelloApplet extends Applet,20,类首部,(6)implements(实现) implements InterfaceNameList; 表明这个类实现了哪些接口。 实现的接口可以有多个。 如: public class HelloApplet extends Applet implements ActionListener,Myinterface,21,4.1.2 类体,定义了该类所有的属性和该类所支持的方法。 其形式说明如下:成员变量说明构造方法说明类方法说明 三部分都是可选的。 三部分没有先后顺
10、序之分,建议按照上面的顺序说明。,22,1.成员变量,访问说明符 数据类型 变量名 访问说明符:成员变量可访问的的范围。 friendly:同包内 public:同项目 private:本类内 protected:子类内 final:常量 类型可以是基本类型,也可以是类。,23,成员变量,例: Person类 package ch4; public class NewPerson private String name; String idNo; /friendly protected Address adr; public boolean sex;final String classNo=“
11、0801“; ,24,package ch4; public class NewPerson private String name; String idNo; /friendly protected Address adr; public boolean sex; final String classNo=“0801“; public static void main(String args)NewPerson np = new NewPerson();np. ,package ch4; public class NewPerson private String name; String i
12、dNo; /friendly protected Address adr; public boolean sex;final String classNo=“0801“; ,25,package ch4; public class UseNewPerson public static void main(String args)NewPerson np = new NewPerson();np. ,package ch4; public class NewPerson private String name; String idNo; /friendly protected Address a
13、dr; public boolean sex;final String classNo=“0801“; ,26,package ch3; import ch4.NewPerson; public class UseNewPerson public static void main(String args)NewPerson np = new NewPerson();np. ,package ch4; public class NewPerson private String name; String idNo; /friendly protected Address adr; public b
14、oolean sex;final String classNo=“0801“; ,27,package ch4; public class UseNewPerson extends NewPerson public static void main(String args)UseNewPerson np = (UseNewPerson) new NewPerson();np. ,package ch4; public class NewPerson private String name; String idNo; /friendly protected Address adr; public
15、 boolean sex;final String classNo=“0801“; ,28,package ch3; import ch4.NewPerson; public class UseNewPerson extends NewPerson public static void main(String args)UseNewPerson np = (UseNewPerson) new NewPerson();np. ,package ch4; public class NewPerson private String name; String idNo; /friendly prote
16、cted Address adr; public boolean sex;final String classNo=“0801“; ,29,成员变量,例4-9线段类Line,其两个端点用点表示,它的属性类型是Point类。 package ch4; / Point类public class Point private int x;private int y; package ch4; / Line类public class Line Point2 p; ,30,2.类方法,【修饰符】 返回值类型 方法名(参数列表) throws 异常列表 局部变量;完成方法功能的语句列表; 如:public
17、static void main(String args) throws IOException ,31,类方法,访问说明符: friendly:同包内.默认 public:同项目 private:本类内 protected:子类内 返回值类型和形参类型: 基本数据类型 类类型 方法体:实现方法功能的程序段。,32,(体现对象特征和行为的概念) public class Quad /类首部 private double a, b, c; /成员变量 private double d, x1, x2; /构造方法 public Quad(double a, double b, double c)
18、 this.a = a;this.b = b;this.c = c; ,利用面向对象的语言求一元二次方程的根,33,利用面向对象的语言求一元二次方程的根,public double getA() return a; /读方法public void setA(double a) this.a = a; /写方法public double getB() return b; ,public void setB(double b) this.b = b; public double getC() return c; public void setC(double c) this.c = c; ,34,
19、利用面向对象的语言求一元二次方程的根,public double getD() return d; public void setD() d = b * b - 4 * a * c; public double getX1() return x1; ,public void setX1() x1 = (-b + Math.sqrt(d ) / (2 * a); public double getX2() return x2; public void setX2() x2 =(-b - Math.sqrt(d ) / (2 * a); ,35,利用面向对象的语言求一元二次方程的根,public
20、void getRoot() /类方法setD();System.out.println(“d=“ + getD();if (d = 0) setX1();setX2();System.out.println(“x1=“ + x1);System.out.println(“x2=“ + x2);,36,利用面向对象的语言求一元二次方程的根, else if (d 0) setX1();setX2();System.out.println(“x1=“ + x1);System.out.println(“x2=“ + x2);,37,利用面向对象的语言求一元二次方程的根, else /d0doub
21、le xreal = 0, xvirtual = 0; / xreal为根的实部,xvirtual为根的虚部xreal = (-b) / (2 * a);xvirtual = Math.sqrt(-d ) / (2 * a);System.out.println(“x1=“ + xreal + “+“ + xvirtual + “i“);System.out.println(“x2=“ + xreal + “-“+ xvirtual + “i“); ,38,利用面向对象的语言求一元二次方程的根,public class UseQuad /类首部public static void main(S
22、tring args) /主方法Quad quad1 = new Quad(1.0, 2.0, 1.0), quad2 = new Quad(1.0, 3.0, 2.0), quad3 = new Quad(1.0, 3.0, 4.0);System.out.println(“一元二次方程“+quad1.getA()+“*x*x+“+quad1.getB()+“x+“+quad1.getC()+“=0的根为:“);quad1.getRoot();System.out.println(“一元二次方程“+quad2.getA()+“*x*x+“+quad2.getB()+“x+“+quad2.ge
23、tC()+“=0的根为:“);quad2.getRoot();System.out.println(“一元二次方程“+quad3.getA()+“*x*x+“+quad3.getB()+“x+“+quad3.getC()+“=0的根为:“);quad3.getRoot(); ,39,3.构造方法,【修饰符】 类名(参数列表)throws异常列表/成员变量初始化语句 功能:在类构造其对象时,对对象进行初始化。 每个类都至少有一个构造方法。 一个类的构造方法可以有多个(方法重载)。 类中没有定义构造方法,Java自动提供缺省的无参构造方法。确保每个Java类都至少有一个构造方法。 自定义的构造方法
24、根据参数的类型、个数来区分。 一旦定义新的构造方法,缺省无参的构造方法失效,若需要无参的构造方法,必须重新定义。,40,构造方法,public 类名() /缺省的,隐式的,不需定义的 public 类名(参数列表1) /显式定义 public 类名(参数列表2) /显式定义,41,(1)缺省的构造方法,package ch4; public class Point_0 private int x; / 属性定义 private int y; public int getX() return x; / 读x public int getY() return y; / 读y public void
25、 setX(int newX) x = newX; / 写x public void setY(int newY) y = newY; / 写y double distance() return Math.sqrt(x * x + y * y); / 求点到原点的距离,42,public static void main(String args) / 主方法Point_0 p1 = new Point_0();/ 引用缺省构造方法System.out.println(“(“ + p1.x + “,“ + p1.y + “)“ + “ distance:“+ p1.distance(); /(0
26、,0) distance:0.0 ,43,(2)带参数的构造方法,package ch4; public class Point_1 private int x; / 属性定义 private int y; public Point_1() /构造方法this.x = 0;this.y = 0; public Point_1(int x, int y) /构造方法this.x = x;this.y = y; ,44,public int getX() return x; / 读x public int getY() return y; / 读y public void setX(int new
27、X) x = newX; / 写x public void setY(int newY) y = newY; / 写y,45,double distance() return Math.sqrt(x * x + y * y); / 求点到原点的距离 public static void main(String args) / 主方法Point_1 p1 = new Point_1(3,4); / 引用带参数的构造方法Point_1 p2 = new Point_1(); / 引用无参数的构造方法System.out.println(“(“ + p1.x + “,“ + p1.y + “)“ +
28、 “ distance:“+ p1.distance();/(3,4) distance:5.0System.out.println(“(“ + p2.x + “,“ + p2.y + “)“ + “ distance:“+ p2.distance();/(0, 0) distance:0.0 ,46,4.对象构造,类名 对象名=new 构造方法名(); 为对象分配存储单元,初始化对象的属性值。 例如: Point_1 p1=new Point_1(); /构造了点(0,0) public Point_1() /构造方法this.x = 0;this.y = 0; Point_1 p2=new
29、 Point_1(1,2); /构造了点(1,2) public Point_1(int x, int y) /构造方法this.x = x;this.y = y; ,47,5.一个Java源文件同时定义多个类,一个.Java源文件内可同时定义多个类; 最多只能有一个public类,该类和文件名同名。,48,MultiClassDemo.java package ch4; class A public int x;public int y;public void add() System.out.println(x + y); class B public float m;public flo
30、at n;public void mySqrt() System.out.println(Math.sqrt(m * m + n * n); ,49,public class MultiClassDemo public static void main(String args) A a = new A();B b = new B();a.x = 6;a.y = 8;a.add(); /14b.m = 3.0f;b.n = 4.0f;b.mySqrt(); /5.0 ,50,4.2 继承与多态,继承(Inheritance)支持着软件代码的复用,是提高软件开发效率的重要因素之一。 继承是在已有类
31、(父类或超类)的基础上派生出新的类(子类),新的类能够吸收已有类的属性和行为,并扩展新的能力。 继承 子类继承父类的属性和行为。 子类又有自己的属性和行为。 子类可以对父类的特征和行为重定义或部分修改。 继承反映了对象共性与个性的关系。,51,继承,例如: class Vehicle / Vehicle的成员定义, Car、Motocycle和Truck的公共属性 class Car extends Vehicle / Car新增加成员的定义 class Motocycle extends Vehicle / Motocycle新增加成员的定义 class Truck extends Vehi
32、cle / Truck新增加成员的定义,52,继承(续),继承分为单继承和多继承。 单继承是指一个子类最多只能有一个父类。 多继承是一个子类可有二个以上的父类。 Java语言中的类只支持单继承,而接口支持多继承。,53,object,Win,DialogWin,单继承 java,Class 1,Class 4,Class 2,Class 3,多继承 C+,54,4.2.1 继承,Java类继承的形式如下:访问说明符 class 子类名 extends 超类名 implements 接口名列表,55,继承,父类必须是在当前编译单元中可以访问的类。 子类继承其父类所有非私有说明的属性和方法。 子类
33、可以对父类的方法重载或覆盖。 重载:方法名相同,形参列表不同,并且重新实现了该方法。 覆盖:方法名相同,形参列表相同,并且重新实现了该方法。 子类属性与父类的属性同名,则父类的该属性被隐藏。,56,/ CEmployee.java package ch4; class Employee public String name;/ 名字 public int salary;/ 薪水 public static String getSalary(String name, int salary) String str;str = “名字: “ + name + “ Salary: “ + salary
34、;return str; public static String getSalary2(String name, int salary) String str;str = “名字: “ + name + “ Salary: “ + salary;return str; ,57,public class CEmployee extends Employee String id = new String(); /子类的新成员 public static String getSalary(String name, int salary) /覆盖父类同名方法String str;if (salary
35、 5000) str = “名字: “ + name + “ Salary: “ + salary;else str = “名字: “ + name + “ Salary: 低于5000“;return str; ,58,public static String getSalary3(String name, int salary,String id) /子类的新方法String str;if (salary 5000) str = “工号: “ + id + “名字: “ + name + “ Salary: “ + salary;else str = “工号: “ + id + “名字:
36、“+ name + “ Salary: 低于5000“;return str; ,59,public static void main(String args) Employee ee = new CEmployee();System.out.println(“覆盖的方法调用:“ +ee.getSalary(“王一“, 500); /覆盖的方法调用:名字: 王一 Salary: 低于5000System.out.println(“继承的方法调用:“ + ee.getSalary2(“王一“, 500);/继承的方法调用:名字: 王一 Salary: 500System.out.println(
37、“覆盖的方法调用:“ + ee.getSalary3(“王飞”, 10000,“001”); /覆盖的方法调用:工号:001 名字: 王飞 Salary: 10000 ,60,继承关联,空心三角箭头线类继承关联。 指向父类。,61,继承关联,62,4.2.2 null、this、super,每个类均定义3个对象值:null、this、super,63,null,null:指代“空”对象; 即该类不存在相应的对象; 如:Point p1=null; /没有构造相应的对象,只是声明,该对象名不能再被定义,64,this,This:指代“当前”对象; 系统自动将this与当前对象的变量相关联。str
38、 = “名字: “ + name + “nSalary: “ + salary; 可以换成:str = “名字: “ + this.name + “nSalary: “ + this.salary;,65,this,package ch4;public class TriPoint extends Point_1 private int z;public TriPoint(int x, int y, int z) super(x, y);this.z = z;public int getZ() return z; TriPoint tp = new TriPoint(1,2,3); this.
39、z = z; tp.z = 3 int a = tp.getZ();,66,super,super:指代直接“父”对象。 super作为方法名代表父类的构造方法。,67,super,package ch4;public class TriPoint extends Point_1 private int z;public TriPoint(int x, int y, int z) super(x, y);this.z = z;public int getZ() return z; TriPoint tp = new TriPoint(1,2,3); /this.z = z; tp.z = 3
40、int a = tp.getZ();,68,继承,Person:name,IdNo,sex,addStudent:stNo,corseId super(name,IdNo,sex,add)=Person(name,IdNo,sex,add)C_Student:os,compile super(name,IdNo,sex,add,stNo,corseId)=Student(name,IdNo,sex,add,stNo,corseId),69,package ch4; class Employee1 public String name;/ 名字public int salary;/ 薪水/ 方法
41、public String getSalary() String str;str = “名字: “ + name + “nSalary: “ + salary;return str; ,70,class Manager extends Employee1 public String department;/ 部门/ 方法public String getSalary() / 使用super变量调用超类Employee1的方法getSalary() return super.getSalary() + “nDepartment: “ + department; ,71,public class
42、UseSuper public static void main(String args) Manager m = new Manager();m.name = “王飞“;m.salary = 10000;m.department = “业务部“;System.out.println(m.getSalary();/调用Manager类的方法getSalary() ,72,4.2.3 多态性,例4-14 多态示例。 package ch4; public class Point protected int x;protected int y;protected Point(int x, int
43、y) this.x=x; this.y=y;public void draw() /父类的draw()方法System.out.println(“Point:a point“); ,73,多态性,多态性(Polymorphism):指在超类中定义的属性或行为,被子类继承之后,可以具有不同的数据类型或表现出不同的行为。 这使得同一个属性或行为在超类及其各个子类中具有不同的语义。 子类可以对父类的方法重载或覆盖。 重载:方法名相同,形参列表不同,并且重新实现了该方法。 覆盖:方法名相同,形参列表相同,并且重新实现了该方法。 继承是多态性的前提条件。,74,多态性(续),几何图形父类:Shape方法
44、draw():具有“画图”行为,但具体画什么图并不确定; 子类:Circle(圆)和Rectangle(矩形)中“画图”的具体行为可重新定义为: 圆类中draw():画圆 矩形类中draw():画矩形 Shape s1 = new Circle(); Shape s2 = new Rectangle();s1.draw();s2.draw();/指向对象不同会画出不同的图形(圆或矩形),75,package ch4; public class ColorPoint extends Point protected int color;protected ColorPoint(int x,int
45、y,int color) super(x,y);this.color=color;public void draw() /子类ColorPoint的draw()方法/覆盖了Point父类的draw()方法System.out.println(“ColorPoint: a color point. “); ,76,package ch4 ; public class MapPoint extends ColorPoint String name; /地图上的点的名字,如城市名protected MapPoint(int x,int y,int color,String name) super(x
46、,y,color);this.name=name;public void draw(String name) /子类MapPoint的draw()方法/覆盖了ColorPoint父类的draw()方法System.out.println(“MapPoint: a map color point. “+name); ,77,package ch4; public class UseAllPoint public static void main(String args)Point p1=new Point(1,2);Point p2=new ColorPoint(1,2,3);Point p3=
47、new MapPoint(1,2,3,“123“);p1.draw();/Point的draw()方法p2.draw(); /ColorPoint的draw()方法p3.draw(); /MapPoint的draw()方法p3.draw(“123”); /MapPoint的draw()方法 ,78,运行此程序,输出结果如下: Point:a point ColorPoint: a color point. ColorPoint: a color point. MapPoint: a map color point. 123,79,4.2.4 final和static,1.final 修饰类:该
48、类是原子类,不能被继承。 修饰属性变量:该变量是常量。 修饰方法:该方法不能被覆盖,但可以重载。作用:增强代码的安全性。,80,final类,public final class TestFinal public class UseFinal extends TestFinal/类型 UseFinal 不能成为终态类 TestFinal 的子类 ,81,final属性,public class TestFinal final int x=100; /*final int x; /空白终态字段 m 可能尚未初始化*/ int y; public TestFinal() this.y = 0; public TestFinal(int y) this.y = y; ,