第八讲 类的多态
主要内容 对象的类型转换 抽象类和抽象方法 接口的创建和使用 |
对象的类型转换
基本类型可以自动转换,强制转换。对象类型也允许转换。
向上转型
class A{
A(){System.out.println("A()");}
void f(){System.out.println("A.f()");}
}
class B extends A{
void f(){System.out.println("B.f()");}
// void g(){System.out.println("B.g()");}
public static void main(String[] aa){
A a=new A();
A b=new B();
a.f();
b.f();
}
}
² 父类对象引用可指向子类对象。
² 子类对象引用不可指向父类对象。
² 向上转型过程中,将丢失本类特有的方法和数据。
思考 1. 若类B中无f方法,程序的运行结果是? 2. 若在main方法中,添加语句B c=new A();,程序可否通过编译? 3. 若取消注释,添加语句b.g();,可否? |
向下转型
class A{
A(){System.out.println("A()");}
void f(){System.out.println("A.f()");}
}
class B extends A{
void f(){System.out.println("B.f()");}
void g(){System.out.println("B.g()");}
public static void main(String[] aa){
A a=new B();
B b=(B)a;
a.f();
b.f();
// a.g();
b.g(); //分析其合法性
}
}
² 向下转型只能针对指向子类对象的基类对象引用进行
² 向下转型语法:(子类名)基类对象引用
² 向下转型后将重新拥有子类特有的方法和数据。
抽象类和抽象方法
抽象类
² 抽象类是对一系列类的抽象,为一系列类制定一个框架。
² 抽象类提供了操纵一系列的类的通用的界面,而不需要具体实现。
² 抽象类的定义:
[权限修饰] abstract class 类名{……}
² 抽象类的意义在于继承。抽象类不能生成对象。
抽象方法
抽象类中的方法可以是抽象的,即只给出方法的原型,而无实现的方法体。
方法的实现可在继承抽象类的子类中定义。
抽象方法的定义:
abstract类型 方法名(参数);
abstract void ab();——对
abstract void ab(){ };——错
思考 1. 什么形式的类为抽象类? 2. 什么形式的方法叫抽象方法? 3. 抽象类可以用new运算符生成对象吗? 4. 抽象类有什么用? 5. 抽象方法在哪里得到细节的具体实现? 6. 抽象类中可以有一般的非抽象的方法吗? |
abstract class Shape{
abstract double getL();
abstract double getS();
void printSL(){
System.out.println("周长:"+getL()+"\t面积:"+getS());
}
}
class Circle extends Shape{
double r;
Circle(double x){r=x;}
double getL(){return 2*Math.PI*r;}
double getS(){return Math.PI*r*r;}
}
class Triange extends Shape{
double a,b,c;
Triange(double x,double y,double z){
a=x;
b=y;
c=z;
}
double getL(){return a+b+c;}
double getS(){
double l=(a+b+c)/2;
return Math.sqrt((l-a)*(l-b)*(l-c)*l);
}
}
class Square extends Shape{
double a,b;
Square(double x,double y){
a=x;
b=y;
}
double getL(){return 2*(a+b);}
double getS(){return a*b;}
}
class Test{
public static void main(String[] aa){
Shape s=new Triange(3,4,5);
s.printSL();
s=new Square(4,6.5);
s.printSL();
s=new Circle(4.5);
s.printSL();
}
}
多态性:同一个方法对不同的对象调用可具有不同的意义。
练习:按如下要求编程,并分析程序结果。
(1)设计一个抽象类Animal,其中包括一个抽象方法sleep()和调用该方法的goSleep方法;
(2)设计Animal的子类Bird;
(3)设计Animal的子类Fish;
(4)设计Animal的子类Person;
(5)实例化三种不同的Animal对象,并调用goSleep方法。
接口的创建与使用
接口是什么?
接口,interface
接口是比抽象类更抽象的“类”。
n 接口是行为框架,其中定义了一组行为架框。所有的方法都是抽象的,没有具体实现的细节。
n 接口可由类实现,由此间接解决类的多重继承问题。一个类可以继承另一个类,同时实现一系列接口。
n 实现接口的类需明确实行接口,在类中必须提供这些行为的细则。对接口中的所有方法重写。
接口的创建
interface 接口名 [extends 父接口] {
Interface body
}
如显卡接口:
interface VideoCard{ //显卡接口
void display();
String getName();
}
说明:
² 接口中所有的方法都默认是public abstract。不能使用static 、final 、private 、protected等修饰符。
² 其中除了方法,可以设常量(public static final的成员变量)。
² interface前可加权限修饰符,public接口须与程序文件同名。
接口的使用
接口是为类服务的。
接受服务的类定义时要表明实现接口:
class 类名 implements 接口名{……}
类中需重写接口中所有方法(具体实现),所有重写方法必须由public修饰。
接口可用来定义模块与模块通信的一个协议。如对于显卡,厂商要实现显卡,主板上要使用显卡,显卡的提供者和使用者之间必须要有一个协议。
interface VideoCard{ //显卡接口
void display();
String getName();
}
//厂商Dmeng实现显卡
class Dmeng implements VideoCard{
String name;
Dmeng(){name="Dmeng's videocard";}
public void display(){
System.out.println(name+" is working");
}
public void setName(String name){this.name=name;}
public String getName(){return name;}
}
//主板MainBoard使用显卡
class MainBoard{
String cpu;
VideoCard vc;
void setCPU(String cpu){this.cpu=cpu;}
void setVideoCard(VideoCard vc){this.vc=vc;}
void run(){
System.out.println(this.cpu);
System.out.println(vc.getName());
vc.display();
System.out.println("Mainbord is working.");
}
}
一个类可以同时实现多个接口,如图:
interfaceA{ void Afun(); } interfaceB{ void Bfun(); } class Animal implements A,B{ public void Afun(){ System.out.println("interface A 的重写"); } public void Bfun(){ System.out.println("interface B 的重写"); } } |
思考 1. 接口的英文名是? 2. 如何定义接口? 3. 接口中的方法是什么样的? 4. 接口中可否有方法之外的成员? 5. 一个类如何来实现接口? 6. 实现接口的类需要做些什么事情? 7. 接口与抽象类比较不同在哪里? 8. 接口有什么用? |