nullnull JavaEE基础教程 第5章 类的高级特性 5.1 static关键字 5.2 this 关键字 5.3 静态导入 5.4 final关键字 5.5 抽象类与接口 nullstatic 关键字用来声明静态变量和静态方法。例如:
class MyClass {
static int i;
static void increase(){
i ++;
}
}
静态变量和静态方法为类中所有对象所共有,可以不创建对象,直接引用。也称为类变量和类方法。
引用方式:类名.静态变量/静态方法,如:
MyClass.i;
MyClass.increase();
如果在声明时不用static 关键字修饰,则为实例变量和实例方法。返回5.1 static关键字 null一个类通过使用new运算符可以创建多个不同的对象,这些对象将被分配不同的内存空间,准确地说就是不同的对象的实例变量将被分配不同的内存空间,如果类中的成员变量有类变量,那么所有的对象的这个类变量都分配给相同的一处内存。也就是说对象共享类变量,改变其中一个对象的这个类变量会影响其它对象的这个类变量。
静态变量可以通过类名直接访问,也可以通过对象来调用。采用这两种方法取得的结果是相同的。如果是public静态变量,则其它类可以不通过实例化访问它们。
类方法不能访问实例变量,只能访问类变量。类方法可以由类名直接调用,也可由实例对象进行调用。类方法中不能使用this或super关键字。 null对于实例变量必须先生成实例对象,通过该对象访问实例变量。实例方法可以对当前对象的实例变量进行操作,也可以对类变量进行操作,实例方法由实例对象调用。
下面的代码及图5.1说明了实例变量与静态变量关系。
class ABCD {
char data;
static int st_data;
}
class Demo {
ABCD a,b,c,d
}null例5-1 关于实例成员和类成员的例子。
程序清单:ch05\MemberTest.java
package ch05;
class Member {
static int classVar;
int instanceVar;
static void setClassVar(int i) {
classVar=i;
// instanceVar=i; // 类方法不能访问实例变量
}
static int getClassVar(){ nullreturn classVar;
}
void setInstanceVar(int i){
classVar=i; //实例方法不但可以访问类变量,也可以实例变量
instanceVar=i;
}
int getInstanceVar( ) {
return instanceVar;
}
}nullpublic class MemberTest{
public static void main(String[] args) {
Member m1=new Member();
Member m2=new Member();
m1.setClassVar(1);
m2.setClassVar(2);
System.out.println("m1.classVar="+m1.getClassVar()+" m2.ClassVar="+m2.getClassVar());
m1.setInstanceVar(11);
m2.setInstanceVar(22);
System.out.println("m1.InstanceVar="+m1.getInstanceVar()+" m2.InstanceVar="+m2.getInstanceVar());
}
} null
分析
定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析
一个不正确的变量引用实例:
class StaticError{
String mystring=“hello”; //实例变量
public static void main(String[] args) {
System.out.println(mystring); //静态方法访问实例变量出错
}
}
错误信息:can’t make a static reference to nonstatic variable。因为只有对象的方法可以访问对象的变量。null解决的办法:
1. 将实例变量mystring改为类变量:
class StaticError{
static String mystring=“hello”;
public static void main(String[] args) {
System.out.println(mystring);
}
}
2.将实例变量mystring改为局部变量:
class NoStaticError{
public static void main(String[] args) {
String mystring=“hello”;
System.out.println(mystring);
}
}返回null例5-2 下面例子中的梯形对象共享一个static的下底。
程序清单:ch05\CommonLader.java
package ch05;
class 梯形{
float 上底,高; //实例变量
static float 下底; //实例变量
梯形(float x,float y,float h) { //构造方法
上底=x; 下底=y; 高=h;
}
float 获取下底() {
return 下底;
}
void 修改下底(float b) {
下底=b;
}
}nullpublic class CommonLader{
public static void main(String[] args){
梯形 laderOne=new 梯形(3.0f,10.0f,20);
梯形 laderTwo=new 梯形(2.0f,3.0f,10);
System.out.println("laderOne的下底:"+laderOne.获取下底());
System.out.println("laderTwo的下底:"+laderTwo.获取下底());
laderTwo.修改下底(60);
System.out.println("laderOne的下底:"+laderOne.获取下底());
System.out.println("laderTwo的下底:"+laderTwo.获取下底());
}
}
null当Java程序执行时,类的字节码文件被加载到内存,如果该类没有创建对象,类的实例成员变量不会被分配内存。但是,类中的类变量,在该类被加载到内存时,就分配了相应的内存空间。如果该类创建对象,那么不同对象的实例变量互不相同,即分配不同的内存空间,而类变量不再重新分配内存,所有的对象共享类变量,即所有的对象的类变量是相同的一处内存空间,类变量的内存空间直到程序退出运行,才释放所占有的内存。 null实例方法和类方法的区别:
对于类中的类方法,在该类被加载到内存时,就分配了相应的入口地址。从而类方法不仅可以被类创建的任何对象调用执行,也可以直接通过类名调用。类方法的入口地址直到程序退出才被取消。
当类的字节码文件被加载到内存时,类的实例方法不会被分配入口地址。当该类创建对象后,类中的实例方法才分配入口地址,从而实例方法可以被类创建的任何对象调用执行。需要注意的是,当创建第一个对象时,类中的实例方法就分配了入口地址,当再创建对象时,不再分配入口地址,也就是说,方法的入口地址被所有的对象共享,当所有的对象都不存在时,方法的入口地址才被取消。
无论是类方法或实例方法,当被调用执行时,方法中的局部变量才被分配内存空间,方法调用完毕,局部变量即刻释放所占的内存。在一个方法被调用执行完毕之前,如果该方法又被调用,那么,方法的局部变量会再次被分配新的内存空间,比如,方法在递归调用时,方法中的局部变量会再次被分配新的内存空间。 nullthis关键字可以出现在类的实例方法中,代
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
使用该方法的当前对象。
为了说明this的用法,下面例子中的“三角形”的构造方法中,有意使用了 this。当使用构造方法来创建对象时,构造方法中的this就代表当前对象。 5.2 this 关键字 null例5-3 “三角形”的构造方法中的this就代表当前对象。
程序清单:ch05\Triangle.java
package ch05;
class 三角形{
double a,b,c;
三角形(double a,double b,double c) { //构造方法
setABC(this,a,b,c); //调用实例方法
}
void setABC(三角形 trangle,double a,double b,double c) { //实例方法,供构造方法调用初始化实例对象。
trangle.a=a;
trangle.b=b;
trangle.c=c;
}
}
class Triangle{
public static void main(String[] args) {
三角形 tra=new 三角形(3,4,5);
System.out.print("三角形型的三边是:"+tra.a+","+tra.b+","+tra.c+",");
}
} null实例方法可以操作类的成员变量,实际上,当成员变量在实例方法中出现时,默认的格式是:
this.成员变量。如:
class A{
int x,y;
void fun(int x){
this.x=x;
y=x;
}
}
在上述 A 类中的实例方法fun()中出现了this,this就代表使用fun()的当前对象。所以,“this.x”就表示当前对象的变量x,当对象调用方法fun()时,将
函
关于工期滞后的函关于工程严重滞后的函关于工程进度滞后的回复函关于征求同志党风廉政意见的函关于征求廉洁自律情况的复函
数的局部变量x赋给该对象的变量x。当一个对象调用方法时,方法中的成员变量就是指分配给该对象的成员变量。null通常情况下,可以省略成员变量名字前面的“this.”,如成员变量y。但是,当成员变量的名字和局部变量的名字相同时,成员变量前面的“this.”就不可以省略。
同样,类的实例方法可以调用类的其它方法,调用的默认格式是:
this.方法,如:
class B{
void fun( ) {
this.get(); //可省略 this.
}
void get( ) {
System.out.println(“ok”);
}
}null在上述B类中的方法fun()中出现了this,this代表使用方法fun()的当前对象。所以,方法fun()的方法体中this.get()就是调用当前对象的方法get()。也就是说,当某个对象调用方法fun()过程中,又调用了方法get()。由于这种逻辑关系非常明确,一个方法调用另一个方法时可以省略方法名字前面的“this.”。
但是,this不能出现在类方法中,因为类方法可以通过类名直接调用,这时可能还没有任何对象诞生。null例5-4 创建一个有两个方法的类,其中第一个方法使用this,第二个方法不使用this。
程序清单:ch05\Rectangle.java
package ch05;
class Rectangle{ //矩形类
int width; // 矩形的宽
int usethis(int width){ //返回宽度的函数
this. width= width; //this 指自己这个对象
return width;
}
int unusethis(int width){
int w=width;
return w;
}
public static void main(String[] args){
Rectangle r=new Rectangle(); //类对象的实例化
System.out.println("r.width="+r.width+" r.usethis(1)="+r.usethis(1)+" r.width="+r.width);
System.out.println("r.width="+r.width+" r.unusethis(2)="+r.unusethis(2)+" r.width="+r.width);
}
}null例5-5 编译并运行下面的程序,分析运行结果,进一步了解super和this的作用。
程序清单:ch05\SuperDemo.java
package ch05;
mport java.io.*;
class SuperClass{ //定义父类
int x;
SuperClass(){ //父类的构造方法
x=10;
}
void doClass(){
System.out.println("SuperClass.doClass()");
}
}nullclass SubClass extends SuperClass{ //定义子类
int x;
SubClass(){ //子类的构造方法
super() ; //调用父类的构造方法
x =100;
}
void doClass(){ //重写父类的doClass方法
System.out.println("SubClass.doClass()");
}
null void doDemo(){ //演示super和this的方法
int x;
x=1000;
super.doClass( ); //调用父类的doClass方法
doClass( ); //调用本类的doClass方法
System.out.println("super.x="+super.x); //父类的x
System.out.println("this.x="+this.x); //本类的x
System.out.println("x="+x); //本方法的x
}
}
public class SuperDemo{
public static void main(String[] args){ //主方法
SubClass s=new SubClass();
s.doDemo();
}
null分析:此程序中定义了一个父类,子类SubClass继承了父类SuperClass,在主函数中定义SubClass类对象s时,自动调用类SubClass的构造函数SubClass(),在此构造函数中先执行“super() ;”语句,这样就调用类SuperClass的构造方法SuperClass(),因为super来指明超类中的方法。同样在子类方法doDemo()中,执行语句“super.doClass( );”时,则调用父类的方法doClass()。如不用super 来指定的话,则调用的是子类的方法doClass(),这里子类SubClass()的成员方法doClass()重写了父类SuperClass()的成员方法doClass()。
语句“System.out.println("super.x="+super.x);”中super调用的是父类SuperClass的变量x,而语句“System.out.println("this.x="+this.x);”中this调用子类SubClass的变量x,关键字this和super分别用来指明子类和父类中同名的成员变量。这里父类SuperClass的成员变量x、子类SubClass的成员变量x和类方法doDemo()中使用的局部变量x三者同名,则要使用关键字this和super来指定所要使用的变量。如不用则输出的类方法的局部变量,如语句“System.out.println("x="+x);”输出的就是类方法doDemo()的局部变量。这里子类SubClass()的成员变量x隐藏了父类SuperClass()的成员变量x。null在JDK1.5后新加了导入静态方法和静态域的功能。在类中使用静态导入,可以使用其它类中定义的类方法和类变量,而且这些类方法和类变量就像在本地定义的一样。换句话说,静态导入允许在调用其它类中定义的静态成员时,可以不通过类名直接使用类中的静态方法。
一般我们导入一个类都用 import xxx.ClassName;而静态导入语句是:import static xxx.ClassName.*;这里多了static和.*,意思是导入xxx.ClassName这个类里的所有静态方法和静态域。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。以后在这个类中,就可以直接用方法名调用静态方法,而不必用“ClassName.方法名”的方式来调用。 5.3 静态导入 返回null静态导入语句看起来和普通的import语句非常相似。但是,普通import语句从某个包中导入的是一个或所有的类,而静态import语句从某个类中导入的却是一个或所有的类方法以及类变量。需要注意的是:针对一个给定的包,不可能用一行语句静态地导入所有类的所有类方法和类变量。也就是说,不能这样编写代码:
import static java.lang.*; // 编译出错!
如果一个本地方法和一个静态导入的方法有着相同的名字,那么本地方法被优先调用。
例如,源文件顶部添加:import static java.lang.System.*; 那么就可以使用System类的静态方法和静态域,而不必加类前缀。如:
out.println("hello world"); //相当于System.out.println("hello world");
exit(0); //相当于 System.exit(0); null导入静态方法和导入静态域有两个实际的应用:
算术函数,对Math类使用静态导入,就能更自然的使用算术函数。如:sqrt(pow(x,2)+pow(y,2));
笨重的常量,如果需要使用大量带有冗长名字的常量,就应该使用静态导入。如:
Date d = new Date();
if (d.get(DAY_OF_WEEK) == MONDAY)
看起来比if (d.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) 清晰。 null例5-6 导入静态方法举例,计算直角三角形的斜边。
程序清单:ch05\StaticImportTest.java
package ch05;
import static java.lang.Math.sqrt; //导入静态方法sqrt()
import static java.lang.Math.pow; //导入静态方法pow()
class Hypot {
public static void main(String args[]) {
double side1, side2;
double hypot;
side1 = 3.0;
side2 = 4.0;
// 静态导入后,不再须要通过类名Math来调用方法sqrt()和pow().
hypot = sqrt(pow(side1, 2) + pow(side2, 2));
System.out.println("给定RT△的两边边长为:" + side1 + "和" + side2 + ",其斜边边长为:"+hypot);
} nullinal 关键字可以修饰类、类的成员变量和成员方法,但final 的作用不同。
(1) final 修饰成员变量,则成员变量成为常量。为了声明一个final变量,可以在类型之前的变量声明使用final关键字,例如:
final type piVar=3.14159;
可以在任何作用域声明一个final变量。修饰成员变量时,定义时同时给出初始值,而修饰局部变量时不做
要求
对教师党员的评价套管和固井爆破片与爆破装置仓库管理基本要求三甲医院都需要复审吗
。这个语句声明了一个final变量并对它进行了初始化。如果在后面还想给piVar赋其他的值,就会导致编译错误,因为final变量的值不能再改变。 5.4 final关键字 返回null(2) final 修饰成员方法,则该方法不能被子类重写。有些方法希望始终保持它在父类中的定义而不会被子类修改以保证安全,此时可以使用final关键字来阻止方法重写。例如:
public final returnType methodName(paramList){
…
}null(3) final修饰类,则类不能被继承。由于安全性的原因或者是面向对象的设计上的考虑,有时候希望一些类不能被继承,例如,Java中的String类,它对编译器和解释器的正常运行有很重要的作用,不能对它轻易改变,因此把它修饰为 final 类,使它不能被继承,这就保证String类型的唯一性。同时,如果你认为一个类的定义已经很完美,不需要再生成它的子类,这时也应把它修饰为final 类,定义一个final类的格式如下:
final class finalClassName{
……
}
如果一个类被声明为final的,则这个类中的所有方法也自动成为final的。 null(4) final修饰引用类型变量,针对引用类型变量的final修饰符也是容易混淆的地方。实际上final只是修饰引用变量自身的值,例如限定类变量保存的实例地址不能变。至于该变量所引用的对象,内容是否能变,那就管不着了。所以,对于如下语句:
final StringBuffer strConst = new StringBuffer();
可以修改它指向的对象的内容,比如:
strConst.append(" ");
但是不能修改它的值,比如:
strConst = null; null5.5.1抽象类
用关键字abstract修饰的类称为抽象类。同样,用abstract 关键字来修饰一个方法时,这个方法就叫做抽象方法。如:
abstract class abstractClass{ …} //抽象类
abstract returnType abstractMethod([paramlist]) //抽象方法
abstract类与final类正好相反,是指不能直接被实例化的类,必须由子类创建对象。抽象类一般作为其它类的超类,抽象类中的抽象方法只需声明,由继承类提供实现。
抽象类必须被继承,抽象方法必须被重写。一个 abstract 类只关心它的子类是否具有某种功能,并不关心功能的具体行为,功能的具体行为由子类负责实现。若类中包含了抽象方法,则该类必须被定义为抽象类。如果一个类是一个 abstract类的子类,它必须具体实现父类的abstract 方法。abstract 类也可以没有 abstract方法。下面是抽象类必须被继承的例子。 5.5 抽象类与接口返回null例5-7定义了一个抽象类C ,其中声明一个抽象方法callme( ),再定义它的子类D ,并重载方法callme( )。对抽象类进行测试。
程序清单:ch05\TestAbstract.java
package ch05;
abstract class C{
abstract void callme();
void metoo(){
System.out.println("Inside C's metoo() method");
}
}
class D extends C{
void callme(){
System.out.println("Inside D's callme() method");
}
}nullpublic class TestAbstract{
public static void main(String[] args){
C c = new D();
c.callme();
c.metoo();
}
}
null例5-8 在下面的例中,有一个abstract的“图形”类,图形类要求其子类都必须有具体计算面积的功能。
程序清单:ch05\ShapeArea.java
package ch05;
abstract class 图形{
public abstract double 求面积();
}
class 梯形 extends 图形{
double a,b,h;
梯形(double a,double b,double h){
this.a=a;this.b=b;this.h=h;
}
public double 求面积(){
return((1/2.0)*(a+b)*h);
}
}nullclass 圆形 extends 图形{
double r;
圆形(double r){
this.r=r;
}
public double 求面积(){
return(3.14*r*r);
}
}
class 堆{
图形 底;
double 高;
堆(图形 底,double 高){
this.底=底;
this.高=高;
}
null void 换底(图形 底){
this.底=底;
}
public double 求体积(){
return (底.求面积()*高)/3.0;
}
}
public class ShapeArea {
public static void main(String[] args){
堆 zui;
图形 tuxing;
tuxing=new 梯形(2.0,7.0,10.7);
System.out.println("梯形的面积"+tuxing.求面积());
zui=new 堆(tuxing,30);
System.out.println("梯形底的堆的体积"+zui.求体积());
tuxing=new 圆形(10);
System.out.println("半径是10的圆的面积"+tuxing.求面积());
zui.换底(tuxing);
System.out.println("圆形底的堆的体积"+zui.求体积());
}
} 5.5.2接口的定义5.5.2接口的定义采用关键字interface来声明一个接口。
接口的定义包括接口声明和接口体,接口声明的格式如下:
[public] interface interfaceName[extends listOfSuperInterface] { … }
extends 子句与类声明的extends子句基本相同,不同的是一个接口可有多个父接口,用逗号隔开。 Java使用接口的目的是为了克服单继承的限制,因为一个类只能有一个父类,而一个类可以实现多个接口。null接口体包括常量定义和方法定义,常量定义格式为:
type NAME=value;
定义在接口中的变量全部隐含为具有public ,final, static的属性。这意味着该常量被实现该接口的多个类共享,它们不能被实现接口方法的类改变,这些变量还必须设置初值。
方法体定义格式为:(具有 public和abstract属性)
returnType methodName([paramlist]);
如果接口声明为public,则接口中的方法和变量全部为public。
接口是抽象类的一种,只包含常量和方法的定义,而没有变量的定义和方法的实现,且其方法都是抽象方法。 null接口的用处体现在下面几个方面:
通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系。
通过接口指明多个类需要实现的方法。
通过接口了解对象的交互界面,而无需了解对象所对应的类。null例5-9声明接口例子。本例声明了接口Stuednt_info表示学生情况,其中有一个成员变量year和两个成员方法age和output。成员变量year隐含为final和static型,必须设置初值。源程序文件名必须与接口名相同。
程序清单:ch05\Student_info.java
interface Student_info{
int year=2010;
int age();
void output();
}5.5.3接口的实现5.5.3接口的实现接口的实现类似于继承,只是用关键字implements声明一个类将实现一个接口,而不是用extends。在类体中可以使用接口中定义的常量,而且必须实现接口中定义的所有方法。一个类可以实现多个接口,在implements子句中用逗号分开。
接口的实现类声明格式如下:
[〈修饰符〉]class〈类名〉[extends〈超类名〉][implements〈接口名1〉,〈接口名2〉,……]
其中,〈修饰符〉可以是public,也可以省略。如果一个类实现一个接口,则必须实现接口中的所有方法,且方法必须声明为public。如果一个类实现多个接口,则用逗号分隔接口列表。null例5-10 实现接口的类。本例声明的类Stuq实现例5-9定义的接口Student_info,Stu1类中有自己的两个成员变量name和birth_year,实现接口方法age时使用了接口中的变量year的值。
程序清单:ch05\Stu1.java
package ch05;
public class Stu1 implements Student_info { //实现学生情况接口
String name;
int birth_year; //类自己的成员变量
public Stu1(String n1,int y) {
name = n1;
birth_year = y;
}null public int age(){ //实现接口的方法
return year - birth_year;
}
public void output(){ //实现接口的方法
System.out.println(this.name +" "+ this.age()+"岁");
}
public static void main (String[] args) {
Stu1 s1 = new Stu1("李明",1980);
s1.output();
}
} 5.5.4接口的应用5.5.4接口的应用一个类通过使用关键字 implements 声明自己实现一个或多个接口。如果实现多个接口,用逗号隔开接口名。如:
class Dog extends Animal implements Eatable, Sleepable
如果一个类实现了某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体。需要注意的是,在类中实现接口的方法时,方法的名字、返回类型、参数个数及类型必须与接口中的完全一致。特别要注意的是,接口中的方法被默认是public的,所以类在实现接口方法时,一定要用public来修饰。另外,如果接口的方法的返回类型如果不是void的,那么在类中实现该接口方法时,方法体至少要有一个return语句,如果是void型,类体除了两个大括号外,也可以没有任何语句。 5.5.4接口的应用5.5.4接口的应用接口声明时,如果关键字 interface 前面加上 public 关键字,就称这样的接口是一个 public 接口。public 接口可以被任何一个类使用。如果一个接口不加 public 修饰,就称做友好接口类,友好接口可以被同一包中的类使用。
Java 为我们提供的接口都在相应的包中,通过引入包可以使用Java提供的接口。也可以自己定义接口。5.5.4接口的应用5.5.4接口的应用例5-11 定义一个接口,设计两个接口的实现类,这两个类中的接口方法的实现各不相同。
程序清单:ch05\TestInterface.Java
package ch05;
interface Computable{
final int MAX=100;
void speak(String s);
int f(int x);
float g(float x,float y);
}
class China implements Computable{
int xuehao;
public int f(int x){ //不要忘记public关键字.
int sum=0;
for(int i=1;i<=x;i++){
sum=sum+i;
}
return sum;
}5.5.4接口的应用5.5.4接口的应用 public float g(float x,float y){
return 6; //至少有return语句.
}
public void speak(String s){
}
}
class Japan implements Computable{
int xuehao;
public int f(int x){
return 68;
}
public float g(float x,float y){
return x+y;
}
public void speak(String s){ //必须有方法体,但体内可以没有任何语句.
}
}
5.5.4接口的应用5.5.4接口的应用public class TestInterface{
public static void main (String[] args){
China Li; Japan Henlu;
Li=new China(); Henlu=new Japan();
Li.xuehao=991898; Henlu.xuehao=941448;
System.out.println("学号:"+Li.MAX+Li.xuehao+"从1到100 求和"+Li.f(100));
System.out.println("学号:"+Henlu.MAX+Henlu.xuehao+"加法"+Henlu.g(2.0f,3.0f));
}
}
5.5.4接口的应用5.5.4接口的应用如果一个类声明实现一个接口,但没有实现接口中的所有方法,那么这个类必须是 abstract 类,例如:
interface Computable
{ final int MAX=100;
void speak(String s);
int f(int x);
float g(float x,float y);
}
abstract class A implements Computable
{ public int f(int x)
{ int sum=0;
for(int i=1;i<=x;i++)
{ sum=sum+i;
}
return sum;
}
} null接口的语法规则很容易记住,但真正理解接口更重要。在上述例子中如果去掉接口,并把程序中的 Li.MAX,Henlu.MAX 去掉,上述程序的运行没有任何问题,那么为什么要用接口呢?下面进一步加深对接口的理解。
在现实生活中,轿车、卡车、拖拉机、摩托车、客车都是机动车的子类,其中机动车是一个抽象类。如果机动车中有一个抽象方法“收取费用”,那么所有的子类都要实现这个方法,即给出方法体,产生各自的收费行为。 null接口可以增加很多类都需要实现的功能,不同的类可以使用相同的接口,同一个类也可以实现多个接口,接口只关心功能,并不关心功能的具体实现,比如“客车类”实现一个接口,该接口中有一个“收取费用”的方法,那么这个“客车类”必须具体给出怎样收取费用的操作,即给出方法的方法体,不同车类都可以实现“收取费用”,但“收取费用”的手段可能不相同。
接口与其实现类不一定有继承意义,就象各式各样的商品,它们可能隶属不同的公司,工商部门要求都必须具有显示商标的功能,实现同一接口,但商标的具体制作由各个公司自己去实现。null例5-12 设计一个关于收费行为的接口,设计该接口的几个实现类,测试各个实现类的收费功能。
程序清单:ch05\ExampleInterface.java
package ch05;
interface 收费{
public void 收取费用();
}
class 公共汽车 implements 收费{
public void 收取费用(){
System.out.println("公共汽车:一元/张,不计算公里数");
}
}
nullclass 出租车 implements 收费{
public void 收取费用(){
System.out.println("出租车:1.60元/公里,起价3公里");
}
}
class 电影院 implements 收费{
public void 收取费用(){
System.out.println("电影院:门票,十元/张");
}
}nullclass ExampleInterface{
public static void main(String[] args){
公共汽车 七路=new 公共汽车();
出租车 大众=new 出租车();
电影院 更俗剧场=new 电影院();
七路.收取费用();
大众.收取费用();
更俗剧场.收取费用();
}
}5.5.5接口回调5.5.5接口回调接口回调是指可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中。那么该接口变量就可以调用被类实现的接口中的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法。这一过程称为对象功能的接口回调。null例5-13 定义一个接口People,设计该接口的两个实现类Student和Teacher,测试接口回调。
程序清单:ch05\BackInterface.java
package ch05;
interface People {
void peopleList();
}
class Student implements People {
public void peopleList() {
System.out.println("I’m a student.");
}
}
class Teacher implements People {
nullpublic void peopleList(){
System.out.println("I’m a teacher.");
}
}
public class BackInterface {
public static void main(String[] args) {
People a; // 声明接口变量
a =new Student(); // 实例化,接口变量中存放对象的引用
a.peopleList(); // 接口功能回调
a = new Teacher(); // 实例化,接口变量中存放对象的引用
a.peopleList(); // 接口功能回调
}
} 上机题上机题学校中有老师和学生两类人,而在职研究生既是老师又是学生,对学生的被管理和对于教师的
责任
安全质量包保责任状安全管理目标责任状8安全事故责任追究制幼儿园安全责任状占有损害赔偿请求权
管理在他们身上都有体现。
(1)设计两个信息管理接口StudentInterface和TeacherInterface。其中StudentInterface接口包括setFee()方法和getFee()方法,这些方法分别用于设置和获取学生的学费;TeacherInterface接口包括setPay()方法和getPay()方法,分别用于设置和获取老师的工资。
(2)定义一个研究生类Graduate,实现StudentInterface和TeacherInterface接口,它定义的成员变量有name(姓名)、sex(性别)、age(年龄)、fee(每学期学费)、 pay(月工资),并添加返回值为float的方法f(),此方法用于计算年收入。其年收入算法为:每年的总工资减去一年的学费。
(3)在测试类中创建一个姓名为"zhangsan"的研究生,根据每学期的学费和月工资收入,统计他的年收入和学费,如果收入减去学费不足2000元,则输出“需要贷款”信息。 nullThe End