• 1. 第3章 面向对象程序 设计基础
  • 2. 本章主要内容3.1 面向对象的基本概念 3.2 类 3.3 成员方法 3.4 对象 3.5 面向对象特性 3.6 接口 3.7 包
  • 3. 3.1 面向对象的基本概念1、 对象的基本概念 对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。
  • 4. 现实世界中的对象有两个共同特征:形态和行为。
  • 5. 图 3.2 软件对象的变量和方法
  • 6. 2、 类的基本概念 类用class作为它的关键字,例如我们要创建一个汽车类,则可表示为:
  • 7. 3.2.1 定义类 1、 类的一般形式 类由类声明和类体组成,而类体又由成员变量和成员方法组成(如图3.3所示):
  • 8. 一个具体的类的形式
  • 9. 2、类声明 类声明由四部分组成:类修饰符、类关键字class、声明父类、实现接口,其一般形式如下: [public][abstract|final] class 类名 [extends 父类名] [implements 接口列表] { …… }
  • 10. 各组成部分的具体说明 (1) 类修饰符   public:这个public关键字声明了类可以在其他类中使用。缺省时,该类只能被同一个包中的其他类使用。   abstract:声明这个类为抽象类,即这个类不能被实例化。   final:声明该类不能被继承,即不能有子类。也就是说,不能用它通过扩展的办法来创建新类。
  • 11. (2) 类的关键字class   在类声明中,class是声明类的关键字,表示类声明的开始,类声明后面跟着类名,按习惯类名要用大写字母开头,并且类名不能用阿拉伯数字开头。给类名命名时,最好取一个容易识别且有意义的名字,避免A、B、C之类的类名。
  • 12. (3) 声明父类   extends为声明该类的父类,这表明该类是其父类的子类。一个子类可以从它的父类继承变量和方法。extends只能实现单继承。 创建子类格式: class subclass extends 父类名{ …  }
  • 13. (4) 实现接口 在类声明中使用关键字implements实现接口,当要实现有多个接口时,各接口名以逗号分隔,其形式为:   implements 接口1,接口2,···,···  接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。一个类可以实现多个接口,以某种程度实现“多继承”。
  • 14. 3.2.2 成员变量和局部变量   成员变量(在类体中定义,在整个类中都有效); 局部变量(在方法中定义,只在本方法中有效)。 变量
  • 15. 成员变量与成员方法class Car { String type=“SUV”; String color=“黑”; String engine=“涡轮增压”; void Car_stop( )   // 刹车 { } void car_ahead( )    // 前进 { } void car_left(void)   // 左转 { } void car_right(void)  // 右转 { }type 、 color、 engine是成员变量,类中所有方法都可以使用它们成员方法
  • 16. (1)成员变量 最简单的成员变量声明的形式为: 类型 成员变量名; (2)局部变量 在方法中声明的变量以及方法中的参数称为局部变量。 (3)如果局部变量名与成员变量名相同,则成员变量被屏蔽。
  • 17. 如果局部变量名与成员变量名相同,则成员变量被屏蔽。 class Data{ int x=12,y=5; public void sum() { int x=3; //局部变量x屏蔽了成员变量,可用this.x取12 int s; s=x+y; } }
  • 18. Java成员变量和局部变量赋初始值的问题class VariableTest { String userName; //成员变量不需要赋初始值 int age=18; static void test(){ String userName; //局部变量则需要赋初始值,否则无法通过编译 int age=88; System.out.println(this.userName); //正确编译并输出变量初始值null System.out.println(userName); //无法通过编译 //此处报错:the local variable nickName may not have been initialized } static void test2(){ System.out.println(age); //18 局部变量和成员变量的作用范围 } public static void main(String[] args) { test(); test2(); } }
  • 19. 局部变量和成员变量的作用范围如图所示。其中x、y是成员变量,a、b是局部变量。
  • 20. 3.3 成员方法 在Java中,必须通过方法才能完成对类和对象的属性操作。成员方法只能在类的内部声明并加以实现。一般在类体中声明成员变量之后再声明方法。
  • 21. 3.3.1 方法的定义 1、方法的一般形式 返回类型 方法名(数据类型1 参数1,数据类型2 参数2,……) { …   (局部变量定义); …  (方法功能实现); return (返回值); }
  • 22. (1) 方法名( )   方法声明包括方法名、返回类型和参数。 (2) 方法体 方法体是一对大括号“{ }”之间的内容。
  • 23. 2、方法的返回值 在方法定义中,方法的类型是该方法返回值的数据类型。方法返回值是方法向外界输出的信息。根据方法功能的要求,一个方法可以有返回值,也可以无返回值(此时方法的类型为 void型)。方法的返回值一般在方法体中通过return语句返回。 return 语句的一般形式为: return 表达式;
  • 24. 【例3-1】有参方法实例。编写一个方法模块,实现计算1 + 2 + 3 + …… + n的n项和的功能。(见教材P60)1 int mysum(int n) 2 { 3  int i, s = 0; 4  for(i=1; i <= n; i++) 5   s = s + i; 6  return s; 7 }
  • 25. 方法说明: ⑴ 第1行“int mysum(int n)”是方法声明,其中mysum是方法名,方法类型为int类型,表明该方法计算的结果为整型;括号中的“int n”表示n是形式参数,简称形参,其类型为int。形参n此时并没有值。 ⑵ 第2行至第7行是方法体部分,用以实现求和的功能。 ⑶ 第6行是通过“return s;”将求得的和值s返回作为mysum方法的值。
  • 26. 3.3.2 方法的调用1、 方法调用的语法形式 方法调用的语句形式如下: 函数名(实际参数1, 实际参数2, …, 实际参数n); 也就是说,一个方法在被调用语句中,其参数称为实际参数。实际参数简称为实参,方法调用中的实参不需要加数据类型,实参的个数、类型、顺序要和方法定义时的形参一一对应。
  • 27. 【例3-3】方法调用示例,计算1 + 2 + 3 + …… + 100的和。算法设计: 我们在主函数中调用例3-1中计算前n项和的方法模块,将调用函数时,将函数的参数(实参)设置为100。这时,函数mysum的形参n得到具体值100。从而计算1 + 2 + 3 + …… + 100 的和。
  • 28. 1. import javax.swing.*; 2. public class Example3_3 3. { 4.  public static void main(String[] args) 5.  { 6.   float sum = mysum(100); 7.  JOptionPane.showMessageDialog(null, "1 + 2 + 3 + …… + 100 = " + s); 8.  System.exit(0); 9.   } 10.  11.  int mysum(int n) 12. { 13.  int i, s = 0; 14.  for(i = 1; i <= n; i++) 15.   s = s + i; 16.  return s; 17. }
  • 29. 【例3-4】具有多个参数的方法示例。已经三角形的底和高,计算三角形面积。 import javax.swing.*;  public class Example3_4  {   public static void main(String[] args)   { float s = area(3, 4);   JOptionPane.showMessageDialog(null, "三角形面积 = " + s);   System.exit(0);   }     static float area(int x, int h)   { float s; s = (x * h) / 2; return s; }  }   
  • 30. 2、 方法调用的过程以【例3-4】为例,当调用一个方法时,整个调用过程分为4步进行(如图3.8所示): 第1步 方法调用,并把实参的值传递给形参; 第2步 执行被调用方法area()的方法体,形参用所获得的数值进行运算; 第3步 通过return语句将被调用方法的运算结果输出给主调方法; 第4步 返回到主调方法的方法调用表达式位置,继续后续语句的执行。
  • 31. (本页无文本内容)
  • 32. 主程序 子程序A 子程序B PROC_A PRO_B CALL PROC_A CALL PROC_B RETURN RETURN方法调用的过程图
  • 33. 3、  方法调用的传值过程
  • 34. (1)主调方法为实参赋值,将实参值存放到内存中专门存放临时变量(又称动态局部变量)的区域中。这块存储区域称为堆栈。 (2)当参数传递时,主调方法把堆栈中的实参值复制一个备份给被调方法的形参。 (3)被调方法使用形参进行功能运算。 (4)被调方法把运算结果(方法返回值)存放到堆栈中,由主调方法取回。此时,形参所占用的存储空间被系统收回。注意,此时实参值占用的存储单元还在被继续使用。
  • 35. (本页无文本内容)
  • 36. 3.2 类与对象 类和对象是Java的核心和本质。它们是Java语言的基础,编写一个Java程序,在某种程度上来说就是定义类和创建对象。定义类和建立对象是Java编程的主要任务。 
  • 37. 3.2 对象类是一个抽象的概念,而对象是类的具体化。类通过实例化生成对象。 一个对象的生命周期包括三个阶段: 创建、使用和释放。
  • 38. 1、对象的创建创建对象的一般格式为: 类名 对象名 = new 类名([参数列表]); (1) 对象声明: 类名 对象名; (2) 实例化: 对象名 = new 类名( );
  • 39. 2、 对象的使用 类是不能直接使用的,我们只能类实例化后的对象。而对象的使用是通过访问对象变量或调用对象方法。 通过运算符“.”可以实现对对象的变量访问和方法的调用。
  • 40. (1) 访问对象的变量  访问格式: 对象名.成员变量;   例如,设有一个A类其结构如下:    class A { int x; } 对变量x赋值,先创建并实例化类A的对象a,然后再通过对象给变量x: A a = new A(); a.x=5;
  • 41. (2) 调用对象的方法 调用格式: 对象名.方法名([参数列表]); 【例3-8】 用带参数的成员方法计算长方体的体积。 【例3-9】 用对象作为方法的参数计算圆柱体的体积。
  • 42. 用类创建对象—实例化当我们要通过汽车类来创建一个轿车对象,并使用它的刹车行为方法时,则要用下面的格式进行实例化:   //实例化汽车对象  汽车 轿车= new 汽车( ) ;   //引用汽车对象的刹车方法  轿车.刹车( ) ;        
  • 43. 3.3.3 方法重载方法重载是指多个方法享有相同的名字,但是这些方法的参数必须不同,或者是参数的个数不同,或者是参数类型不同。返回类型不能用来区分重载的方法。 方法重载:如果有两个方法的方法名相同,但参数不一致,哪么可以说一个方法是另一个方法的重载。
  • 44. 【例3-5】见教材P64图3.8 重载与调用关系
  • 45. 4.3.4 构造方法 构造方法是一个特殊的方法,主要用于初始化新创建的对象。构造方法的方法名要求与类名相同,而且无返回值。在创建对象时,Java系统会自动调用构造方法为新对象初始化。另外,构造方法只能通过new运算符调用,用户不能直接调用。需要注意的是,我们在这里说构造方法无返回值,并不是要在构造方法名前加上void,构造方法名是不能有void的,如果在构造方法名前加了“void”,系统就不会自动调用该方法了。
  • 46. 【例3-6】 计算长方体的体积。(见教材P66) 1. /* 构造长方体 */ 2. class Box 3. { 4. double width, height, depth; 5. Box() 6. { 7. width = 10; 8. height = 10; 9. depth = 10; 10. } 11. double volume() 12. { 13. return width * height * depth; 14. } 15. } Box类的构造方法,与类同名普通方法,计算长方体体积
  • 47. 16. public class Example3_6 17. { 18. public static void main(String args[]) 19. { 20. Box box = new Box(); 21. double v; 22. v = box.volume(); 23. System.out.println("长方体体积为: " + v); 24. } 25. }
  • 48. 在一个类的程序中,也可以没有定义构造方法,则Java系统会认为是定义了一个缺省构造方法,缺省构造方法是无任何内容的空方法。当编写类的时候,只有在需要进行一些特别的初始化的场合,才需要定义构造方法。
  • 49. 【例3-7】 使用缺省构造方法设计一个计算长方体体积的程序。1./* 缺省构造方法构造长方体类 */ 2. class Box 3. { 4. double width, height, depth; 5. double volume() // 计算长方体体积 6. { 7. width = 10; 8. height = 10; 9. depth = 10; 10. return width * height * depth; 11. } 12. } 该类没有定义构造方法
  • 50. 13. public class Example3_7 14. { 15. public static void main(String args[]) 16. { 17. Box box = new Box(); 18. double v; 19. v = box.volume(); 20. System.out.println("长方体体积为: " + v); 21. } 22. } 应用缺省构造方法创建实例对象
  • 51. 构造方法的重载class Box { double w, h, d; Box() { w = 10; h = 10; d = 10; } Box(float x,float y,float z) { w = x; h = y; d = z; } double volume() { return w * h * d; } }
  • 52. 填空把代码给出一部分,分别用构造方法重载和成员方法重载求4,5,6和40,50,60长方体体积。
  • 53. 成员方法重载 构造方法重载 this 的使用 私有成员变量 修改成员变量 获得成员变量public class Cat { private String name; private int age; private String food="鱼"; public Cat(){} public Cat(String name){ this.name=name; } public Cat(String name,int age){ this.name=name; this.age=age; } public void eat(){ } public void eat(String food){ this.food=food; } public String getName(){ return name; } public int getAge(){ return age; } public void setFood(String food){ this.food=food; } public String getFood(){ return food; } } public class CatDemo { public static void main(String[] args){ Cat cat=new Cat("coffei cat",2); cat.eat("老鼠"); //System.out.println(cat.name); System.out.println(cat.getName()); System.out.println(cat.getAge()); System.out.println(cat.getFood()); Cat cat1=new Cat(); cat1.eat(); System.out.println(cat1.getName()); System.out.println(cat1.getAge()); System.out.println(cat1.getFood()); cat1.setFood("小鱼"); System.out.println(cat1.getFood()); } }
  • 54. //谁的速度快public class Lx3_1 { Lx3_1(){ System.out.println("gouzhao x="+x); } public static void main(String[] args) { Lx3_1.test();//类名.方法 lx.test();//对象名.方法 Lx3_1 lx=new Lx3_1(); lx.test1(); } static int x=18; int y=30; static { System.out.println("我是static块"); System.out.println("知道static块吗?"); System.out.println("static x="+x); Lx3_1.test();//类名.方法 lx.test();//对象名.方法 } static void test(){ System.out.println("我是static方法"); System.out.println("test x="+x); } { System.out.println(“ 非静态块"); } void test1() { System.out.println("test1 x="+x); } }
  • 55. //谁的速度快 排序后public class Lx3_1 { static int x=18; static //静态代码块 { System.out.println("我是static块"); System.out.println("static x="+x); Lx3_1.test(); //类名.方法 lx.test();//对象名.方法test();//直接调用 } static void test(){ System.out.println("我是static方法"); System.out.println("test x="+x); } public static void main(String[] args) { Lx3_1 m1=new Lx3_1(); System.out.println(""+m1.y); m1.test1(); } { System.out.println(“ 非静态块"); } int y=30; Lx3_1() { System.out.println(y);} void test1(){ System.out.println("我是test1方法"); System.out.println("test1 x="+x); } }
  • 56. 3.5 面向对象特性java语言中有三个典型的面向对象的特性: 封装性、 继承性 多态性 。
  • 57. 封装性 public及默认 对于类package pac; public class Box { float w; float h; float d; public Box(){ w=10; h=10; d=10; } public Box(float x,float y,float z) { w=x; h=y; d=z; } public double volume() { return w*h*d; } }
  • 58. 封装性 public和默认 对于类import pac.Box; class Ex3_8 { public static void main(String[] args) { Box b1=new Box(); System.out.println(b1.volume()); Box b2=new Box(12.0f,12.5f,13.0f); System.out.println(b2.volume()); } }
  • 59. protected class Box { protected float w; protected float h; protected float d; protected Box(){ w=10; h=10; d=10; } protected Box(float x,float y,float z) { w=x; h=y; d=z; } protected double volume() { return w*h*d; } }
  • 60. protected class Ex3_8 { public static void main(String[] args) { Box b1=new Box(); System.out.println(b1.volume()); Box b2=new Box(12.0f,12.5f,13.0f); System.out.println(b2.volume()); System.out.println(b2.w); } }
  • 61. private class Box { private float w; private float h; private float d; private Box(){ w=10; h=10; d=10; } private Box(float x,float y,float z) { w=x; h=y; d=z; } private double volume() { return w*h*d; } public static void main(String[] args) { Box b1=new Box(); System.out.println(b1.volume()); Box b2=new Box(12.0f,12.5f,13.0f); System.out.println(b2.volume()); System.out.println(b2.w); System.out.println(b2.h); System.out.println(b2.d); } }
  • 62. 多继承 Get() AGet() CGet() B
  • 63. 多重继承 ABC
  • 64. 方法的覆盖:正如子类可以定义与父类同名的成员变量,实现对父类成员变量的隐藏一样,子类也可以重新定义与父类同名的方法,实现对父类方法的覆盖。当在子类中调用同名的方法时,一般情况下是调用它自己定义的方法,因而实现了对父类方法的覆盖,如果要调用父类的方法,只需在方法名前使用不同的类名或对象名即可变量的隐藏:如果在子类中对从父类继承来的成员变量进行重新定义,即出现了子类变量对父类变量的隐藏。所谓隐藏是指子类拥有两个相同名字的变量,一个是继承自父类,另一个是由自己定义的。当子类执行它自己定义的方法时,如果操作该变量,所操作的是它自己定义的变量,而把继承自父类的变量“隐藏”起来。当子类执行从父类继承的操作时,如果操作该变量,所操作的是继承自父类的成员变量。
  • 65. 什么是向上转型?Shape s=new Circle();
  • 66. 你有什么用public class Person { public int maxage=150; //继承的 public String name ="人类"; //被隐藏的 public void eat(){ //继承的 System.out.println("人类吃饭方法"); } public void say(){ //被覆盖的 System.out.println("人类说话方法"); } } public class Student extends Person{ public String name ="学生"; public String grade ="十年级"; //新加的 public void say(){ System.out.println("学生说话方法"); } public void study(){ //新加的 System.out.println("学生学习方法"); } } 上转型对象是将子类的对象赋值给父类的引用,形如: SuperClass sup = subClass;public class Test {       public static void main(String [] args){           Person p = new Student();  //上转型对象         p.say();//输出学生说话方法           p.eat();//输出人类吃饭方法           p.study();  //报错         System.out.println(p.name);//输出人类临时变量           System.out.println(p.grade);  //报错     }   }  
  • 67. 你有什么用 public String grade public void study(){ } public int maxage=150  public void eat(){ } public String name =“人类”;   public void say(){           System.out.println("学生说话方法");       }  
  • 68. 你有什么用——没有上转型的话public class Monitor{//显示器类       public void displayText() {}       public void displayGraphics() {}   }   public class LCDMonitor extends Monitor {//液晶显示器类       public void displayText() {           System.out.println("LCD display text");        }       public void displayGraphics() {           System.out.println("LCD display graphics");       }   }   public class CRTMonitor extends Monitor {//阴极射线管显示器类       public void displayText() {           System.out.println("CRT display text");       }       public void displayGraphics() {           System.out.println("CRT display graphics");       }   }   public class PlasmaMonitor extends Monitor {//等离子显示器 public void displayText() {        System.out.println("Plasma display text"); } public void displayGraphics() {        System.out.println("Plasma display graphics"); } } public class MyMonitor { public static void main(String[] args) { LCDMonitor m1= new LCDMonitor ();   CRTMonitor m2=new  CRTMonitor();       run(m1);  run(m2); } public static void run(LCDMonitor monitor) {        monitor.displayText();        monitor.displayGraphics(); } public static void run(CRTMonitor monitor) {        monitor.displayText();        monitor.displayGraphics(); } public static void run(PlasmaMonitor monitor) {        monitor.displayText();        monitor.displayGraphics(); } }
  • 69. public class MyMonitor 1{ public static void main(String[] args) {       Monitor m1=new LCDMonitor();   //向上转型  run(m1);    Monitor m2=new CRTMonitor();                //向上转型             run(m2);                   } public static void run(Monitor monitor) { //父类实例作为参数       monitor.displayText();        monitor.displayGraphics(); } } 你有什么用——有了上转型的话减少了编程工作量,实现了多态
  • 70. 上转型的作用class phone { private String housing; public void calling (){  System.out.println(“父类打电话!”); } pulic String receivem(){System.out.println(“收短信!”;} } class MOTO_E2 extends phone{ private usb_expansion_board ; public void photo; public void bluetooth ; //这些功能都是在父类的基础上扩展的,也是子类E2类的特色。 public void calling (){  System.out.println(“E2打电话!“); } } phone p1 = new MOTO-E2(); p1只能看原有的功能有什么更新,不能使用新功能
  • 71. 多重继承public class Animal { protected static String kind="Grandfather"; protected String name="Animal"; protected String getname() { return name; } protected static String getkind() { return kind; } }
  • 72. 人类继承了动物public class People extends Animal{ protected static String kind="Father"; protected String name="People"; protected String getname() { return name; } protected static String getkind() { return kind; } protected String getsupername() { return super.name; } }
  • 73. 学生继承了人类public class Student1 extends People{ protected static String kind="Son"; protected String name="Student"; protected String getname() { return name; } protected static String getkind() { return kind; } protected String getsupername() { return super.name; } protected String getsupersupername() { return super.getsupername(); } }
  • 74. 测试类一public class A_P_SDemo { public static void main(String[] args) { Animal a=new Animal(); People p=new People(); Student1 s=new Student1(); System.out.println(a.getname());//运行结果为Animal System.out.println(a.getkind());//运行结果为Grandfather System.out.println(p.getsupername());//运行结果为Animal System.out.println(s.getsupersupername());//运行结果为Animal System.out.println(p.getname());//运行结果为People System.out.println(p.getkind());//运行结果为Father System.out.println(p.name);//运行结果为People System.out.println(s.getsupername());//运行结果为People System.out.println(p.kind);//运行结果为Father System.out.println(s.getname());//运行结果为Student System.out.println(s.getkind());//运行结果为Son System.out.println(s.name);//运行结果为Student System.out.println(s.kind);//运行结果为Son } }
  • 75. 测试类二//变量只会被隐藏 不会被覆盖 //子类的静态方法隐藏 父类中同样标示 //子类的方法覆盖同名父类中的方法 public class A_P_SDemo1 { public static void main(String[] args) { People p=new People(); Student s=new Student(); People pp=new Student(); System.out.println(pp.getname());//运行结果为Student 覆盖! System.out.println(pp.getkind());//运行结果为Father 没有覆盖! System.out.println(pp.name);//运行结果为People 变量没有隐藏! System.out.println(pp.kind);//运行结果为Father 变量没有隐藏! } }
  • 76. 关于继承性【例3-10】创建一个A类和它的子类B类,我们通过子类B的实例对象调用从父类A继承的方法。( 教材P72)
  • 77. super关键字java中通过关键字super来实现对父类成员的访问,super用来引用当前对象的父类。Super 的使用有三种情况: (1)访问父类被隐藏的成员变量或方法,如:     super.variable; (2)调用父类中被重写的方法,如:     super.Method([paramlist]); (3)调用父类的构造方法。由于子类不继承父类的构造方法,当要在子类中使用父类的构造方法时,则可以使用super来表示,并且super必须是子类构造方法中的第一条语句。
  • 78. 子类继承父类举例class Animal {  int height,weight;  void eat(){   System.out.println("animal:eat");  }  void sleep(){   System.out.println("animal:sleep");  }  void breath(){   System.out.println("animal:breath");  } } class Fish extends Animal//继承Animal类 {  int height;  void breath(){//方法的覆盖   System.out.println(“fish:buble”);   super.breath();//可使用super调用父类中的方法和属性   super.weight=18;   System.out.println(super.weight);  } } class Intergration {  public static void main(String[] args){   Animal a=new Animal();   Fish f=new Fish();   a.eat();   a.height=24;   f.breath();   f.weight=4;   System.out.println(a.height);   System.out.println(f.weight);  } }
  • 79. //父类 public class Father{ //父类有一个业余爱好 public void hobby(){} } //子类1 public class Son1 extends Father{ //重写父类的业余爱好 public void hobby(){ System.out.println(“我喜欢的你不一定喜欢!"); } } //子类2 public class Son2 extends Father{ //重写父类的业余爱好 public void hobby(){ System.out.println(“你喜欢的我就喜欢!"); } } //子类3 public class Son3 extends Father{ //重写父类的业余爱好 public void hobby(){ System.out.println(“随便你!"); } }//测试类 public class Test{  public static void main(String args[]){  Father father;  father = new Son1();  father. hobby();  father = new Son2();  father. hobby();  father = new Son3();  father. hobby();  } }   
  • 80. this 关键字 this 是Java的一个关键字,表示某个对象。this可以用于构造方法和实例方法中,但不可以用于类方法中(用static修饰的方法)。 (1)this用于构造方法中时,代表调用该构造方法所创建的对象。 (2)this用于实例方法中时,代表调用该方法的当前对象。 this的使用格式为: this.当前类的成员方法(); 或 this.当前类的成员变量;
  • 81. this举例abstract class ShengWu //生物类为抽象类  { public abstract String Tz() ; } class ZhiWu extends ShengWu // 植物是生物的子类  { String leaf; ZhiWu(String leaf) {this.leaf=leaf; } public String Tz() { return leaf; } } class DongWu extends ShengWu // 动物是生物的子类  { String mouth; DongWu(String mouth) { this.mouth=mouth;} public String Tz() { return mouth; } }public class Example3_14 { public static void main(String args[]) { ZhiWu A = new ZhiWu("叶"); System.out.println("植物的特征:"+A. Tz()); DongWu B = new DongWu("嘴巴"); System.out.println("动物的特征:"+B. Tz()); } }
  • 82. 抽象类总结  java语言中,用abstract 关键字来修饰一个类时,这个类叫做抽象类,用abstract 关键字来修饰一个方法时,这个方法叫做抽象方法。   抽象类必须被继承,抽象方法必须被重写。抽象方法只需声明,无需实现;抽象类不能被实例化,抽象类不一定要包含抽象方法。若类中包含了抽象方法,则该类必须被定义为抽象类。
  • 83. 有两个概念很重要:对象的行为和对象的实现。 如果一个实体可以有多种实现方式,则在设计实体行为的描述方式时,应当达到这样一个目标:在使用实体的时候,无需详细了解实体行为的实现方式。 也就是说,要把对象的行为和对象的实现分离开来。抽象类可以定义不提供具体实现的方法,分离了对象的行为和对象的实现
  • 84. 行为1:查询发动机的马力,发动机将返回一个表示马力的整数。Java代码   public abstract class Motor{                        abstract public int getHorsepower();               }  
  • 85. 行为2:查询电池驱动发动机的充电时间,发动机将返回一个表示充电时间的整数。 用Java方法来描述这个行为,代码如下: Java代码   public abstract class BatteryPoweredMotor extends Motor{                      abstract public int getTimeToRecharge();                    }  
  • 86. 行为3:查询光驱动发动机能够正常运转所需要的最小流明数,发动机返回一个整数。 Java代码   public abstract class SolarPoweredMotor extends Motor{                        abstract public int getLumensToOperate();             }   
  • 87. 如何定义新型的光电驱动发动机?现在销售部门又有了一种新的发动机,它是一种既有电驱动又有光驱动的双重驱动发动机 public abstract DualPoweredMotor extends SolarPoweredMotor, BatteryPoweredMotor{                                           }   Java语言不允许多继承!!!
  • 88. 3.6 接口3.6.1 接口的定义   接口是抽象类的一种,只包含常量和方法的定义,而没有变量,且其方法都是抽象方法。它的用处体现在下面几个方面: (1)通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系。 (2)通过接口指明多个类需要实现的方法。
  • 89. 1、 接口的定义 接口的定义包括接口声明和接口体。 接口定义的格式如下: [public] interface 接口名[extends 父接口名] { …   //接口体 }
  • 90. 2、 接口的实现 在类的声明中用implements子句来表示一个类使用某个接口,在类体中可以使用接口中定义的常量,而且必须实现接口中定义的所有方法。 一个类可以实现多个接口,在implements子句中用逗号分开。
  • 91. 实现多重继承行为1: public interface Motor{ public int getHorsepower(); } 行为2: public interface BPMotor extends Motor{ public int getTimeToRecharge(); }  行为3: public interface SPMotor extends Motor{ public int getLumensToOperate(); }   public interface DualPoweredMotor extends BPMotor,SPMotor{ } public class DualPoweredMotor implements BPMotor,SPMotor{ public int getHorsepower() { return 0; } public int getLumensToOperate() { return 0; } public int getTimeToRecharge() { return 0; } }
  • 92. 收费接口 调温接口public interface Sf { void Ktf(); } public interface Tw { void Ct(); }
  • 93. 公交车public class Bus implements Sf{ public void Ktf() { System.out.println("2"); } }
  • 94. 出租车public class Taxi implements Sf,Tw { public void Ct() { System.out.println("8"); } public void Ktf() { System.out.println("需求"); } }
  • 95. 测试public class Ex3_16 { public static void main(String[] args) { Bus a7=new Bus(); Taxi ty=new Taxi(); a7.Ktf(); ty.Ktf(); ty.Ct(); } }
  • 96. 什么是回调
  • 97. 接口回调interface People {//声明一个接口 void peopleList(); } class Student implements People {//该接口的实现类,客户程序C public void peopleList() { System.out.println("I’m a student."); }} class Teacher implements People {//该接口的实现类,客户程序C public void peopleList() { System.out.println("I’m a teacher."); } }public class Example { public static void main(String args[]) { People a; // 声明接口变量 a = new Student(); // 实例化,接口变量中存放对象的引用 a.peopleList(); //实际上…接口回调 a = new Teacher(); // 实例化,接口变量中存放对象的引用 a.peopleList(); //实际上…接口回调 } }接口回调是指:可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调
  • 98. 原始版—服务程序与调用者合了//1.声明一个接口,包含方法 void peopleList() //2.在服务程序类IExample内将该接口设置为私有成员private IPeople p; //3.在IExample内提供一个方法IExample (IPeople p){},可以将外部“该接口的实现类的引用”通过形参传给p; //4.IExample的某个方法中method()会用到p.peopleList()方法; //5.在IExample的实例中,将实现了IPeople接口的对象的引用传给IPeople,后调用method()方法; interface IPeople {//声明一个接口 void peopleList(); } class IStudent implements IPeople {//该接口的实现类,客户程序C public void peopleList() { System.out.println("I’m a student."); }} class ITeacher implements IPeople {//该接口的实现类,客户程序C public void peopleList() { System.out.println("I’m a teacher."); } }//服务程序S中的某个函数 method(); //客户程序C调用服务程序S中的某个函数method(); //然后S又在某个时候反过来调用C中的某个函数peopleList(),对于C来说,这个peopleList()便叫做回调函数 public class IExample { private IPeople p;//声明接口变量 IExample (IPeople p) { this.p = p;} //实例化,接口变量中存放对象的引用 void method(){ p.peopleList(); //接口回调 } public static void main(String args[]) { IPeople a; // 声明接口变量 a = new IStudent(); // 实例化,接口变量中存放对象的引用 a.peopleList(); new IExample(a).method(); a = new ITeacher(); // 实例化,接口变量中存放对象的引用 a.peopleList(); new IExample(a).method(); } }
  • 99. 3.7 包 在Java语言中,每个类都会生成一个字节码文件,该字节码文件名与类名相同。这样,可能会发生同名类的冲突。为了解决这个问题,Java采用包来管理类名空间。
  • 100. 3.7.1 创建自己的包1、包的定义 把一个源程序归入到某个包的方法用package来实现。 package语句的一般形式为: package 包名; 2、包的引用 import 包名.类名;
  • 101. import语句import java.io.*; import java.applet.*;
  • 102. 【例3-18】创建一个自己的包。package abc.test; public class MyTest {public void print() { System.out.println("package test"); } }import abc.test .*; public class PackageTest {public static void main(String args[ ]) {MyTest mt=new MyTest(); mt.print(); } }(1)在当前目录建立子目录:abc\test (2)把MyTest.java保存到abc\test目录下PackageTest.java保存在当前目录
  • 103. 3.7.2 压缩文件1、将类压缩为jar文件 在Java提供的工具集bin目录下有一个jar.exe文件,它可以把多个类的字节码文件打包压缩成一个jar文件,然后将这个jar文件存放到Java运行环境的扩展框架中,即将该jar文件存放在JDK安装目录的jre\lib\ext下,这样,其他的程序就可以使用这个jar文件中的类来创建对象了。
  • 104. 例:设有Test1.class和Test2.class,我们要将它们压缩成一个jar文件Test.jar。 (1)编写Manifest.mf清单文件 Mainfest –Version: Main-Class: Test1 Test2 (注意Main-Class:与后面的类名之间要有一个空格,且最后一行要回车换行)。将其保存为Manifest.mf。
  • 105. (2)生成jar文件 jar cfm Test.jar Manifest.mf Test1.class Test2.class 其中参数c表示要生成一个新的jar文件,f表示要生成的jar文件的文件名,m表示清单文件的文件名。
  • 106. 2、将应用程序压缩为jar文件 我们还可以用jar.exe将应用程序生成可执行文件。在Windows环境下,我们可用鼠标双击该文件,就可以运行该应用程序。 其生成jar文件的步骤与前面生成类的jar文件相同。当要压缩多个类时,我们在清单文件中只要写出主类的类名,设有主类A.class,则: Mainfest –Version: Main-Class: A
  • 107. 生成jar文件时,也可以使用通配“*.class”。 jar cfm Test.jar Manifest.mf *.class
  • 108. 本章结束!