本章目标
父/子类中的同名成员
父/子类中成员方法仅仅同名 (重载)
class BaseClass //定义基类
{
public void fun()
{
…… //具体实现代码略
}
}
class DerivedClass extends BaseClass //派生类继承于基类
{
public void fun(int x) //跟父类中有相同名称的方法
{
…… //具体实现代码略
}
}
/*如果仅仅只是名称相同,但参数列表不同的话,则构成方法重载*/
父/子类中成员方法同原型 (重写)
class SuperClass //定义父类
{
public void fun()
{
…… //具体实现代码略
}
}
class SubClass extends SuperClass //子类继承于父类
{
public void fun() //与父类中的方法完全同原型
{
…… //具体实现代码略
}
}
/*如果不但名称相同,而且连方法原型也完全相同的话,则构成方法重写*/
方法重写
(补充:)方法签名:包括了方法的:A.形式参数列表 B.返回值类型 C.方法名 (不包含 : 访问控制修饰符)
方法重写示例:
class ParentClass { //定义父类
public void fun() {
System.out.println("这是父类中的方法。");
}
}
class ChildClass extends ParentClass {//子类继承于父类
public void fun() { //子类覆盖父类中的方法
System.out.println("这是子类中的方法。");
}
}
class OverriddenTest { //用于容纳main方法
public static void main(String[] args) {
ParentClass parObj = new ParentClass();
parObj.fun(); //父类的实例调用此方法
ChildClass chiObj = new ChildClass();
chiObj.fun(); //子类的实例调用此方法
}
}
区分方法重写和方法重载
引用转型
BaseClass obj = new DerivedClass();
这样的语句是合法的;
DerivedClass obj = new BaseClass();
这样的语句将引发错误。
引用转型示例:
class Person { //定义人类
……
}
class Student extends Person { //学生类继承于人类
……
}
public class OverriddenDemo {
public static void main(String[] args) {
//正确,所有的学生一定是人
Person per = new Student();
//错误,并不是所有的人都是学生
Student std = new Person();
}
}
问题:
那么通过父类的引用将会调用到哪个类中的方法呢?
示例:
class Shapes { //基本形状类
public void draw() { //绘图的方法
System.out.println("绘制了一个基本形状。");
}
}
class Circle extends Shapes { //圆形类继承于基本形状类
public void draw() { //覆盖父类的绘图方法
System.out.println("绘制了一个圆形。");
}
}
class Square extends Shapes { //正方形类继承与基本形状类
public void draw() { //覆盖父类的绘图方法
System.out.println("绘制了一个正方形。");
}
}
public class polymorphismDemo {
public static void main(String[] args) {
Shapes obj = new Shapes(); //父类的引用指向父类的实例
obj.draw(); //调用绘图方法
obj = new Circle(); //父类的引用指向子类的实例
obj.draw(); //调用绘图方法
obj = new Square(); //父类的引用指向子类的实例
obj.draw(); //调用绘图方法
}
}
多态
静态多态
动态多态
使用多态的优点
示例:(飞行系统)
//具体实现代码省略
public class Plane {
void fly(){…}; // 起飞
void land(){…}; // 着陆
}
public class Copter extends Plane {
void fly(){…}; // 直升机起飞
void land(){….}; //直升机着陆
}
public class Jet extends Plane {
void fly(){…}; // 喷气式飞机起飞
void land(){….}; //喷气式飞机着陆
}
多态的优点
抽象方法
[访问权限] abstract 返回值类型 方法名称(参数列表);
public abstract void draw();
抽象类
[访问权限] abstract class 类名 {
成员列表
}
public abstract class Shapes {
public abstract void draw();
}
抽象类的注意事项
修改前面的示例:
abstract class Shapes { //基本形状类,抽象类
public abstract void draw(); //绘图方法,抽象方法
}
class Circle extends Shapes { //圆形类继承于基本形状类
public void draw() { //实现抽象父类的抽象绘图方法
System.out.println("绘制了一个圆形。");
}
}
class Square extends Shapes { //正方形类继承与基本形状类
public void draw() { //实现抽象父类的抽象绘图方法
System.out.println("绘制了一个正方形。");
}
}
public class abstractDemo { //该类用于容纳main方法
public static void main(String[] args) {
Shapes obj;
obj = new Circle(); //父类的引用指向子类的实例
obj.draw(); //调用绘图方法
obj = new Square(); //父类的引用指向子类的实例
obj.draw(); //调用绘图方法
}
}
接口
[访问权限] interface 接口名 {
成员列表
}
public interface IMyInterface {
……
}
实现接口
[访问权限] class 类名 implements 接口名 {
成员列表
}
public class MyClass implements IMyInterface {
……
}
接口示例
接口的注意事项
接口示例(续)
/*InterfaceDemo.java源文件*/
//导入必要的接口和类
import aaa.IMyInterface;
import bbb.MyClass;
//用于容纳main方法
public class InterfaceDemo
{
public static void main(String[] args)
{
//使用接口的引用指向实现类的实例
IMyInterface obj = new MyClass();
System.out.println("两数的和是:" + obj.add(20, 30));
System.out.println("两数的差是:" + obj.sub(30, 20));
}
}
关于接口的更多知识
public class 实现类名 implements 接口1,
接口2,
……,
接口n
{
成员列表
}
关于接口的更多知识(续)
public interface 子接口名extends 父接口名 {
成员列表
}
final关键字
final修饰变量
[访问权限] final 数据类型 常量名 = 值;
final double PI = 3.14159;
PI成为常量,其后任何试图对PI进行赋值的语句都将报错;
final修饰方法
[访问权限] final 返回值类型 方法名(参数列表) {
……
}
•如:
public final void fun() {
……
}
•如果在派生类中出现同原型的方法,将会报错。
final修饰类
[访问权限] final class 类名 {
成员列表
}
public final class MyClass {
……
}
•任何类想继承于MyClass类都将报错。
类与类之间的关系
总结
作业
Manager和Director类重写父类的抽象方法。
计算Manager的薪资总额totalAmount的公式为:
逻辑趣味思考题
补充阅读
内部类:http://download.youkuaiyun.com/detail/nisior/3848384
抽象类和接口的区别:http://download.youkuaiyun.com/detail/nisior/3848397