编写一个多态性java程序_day6-Java遗传和多态性

遗传性和多态性

遗传性

遗传性允许 Java 复用&扩展 现有代码。

!注意,这里StyledString只是一个理论上的例子,因为String类是最终类,实践中无法被延展和添加特性。

延伸基础的String类,就是要充分利用现有的方法,同时增加一些我们自己的特性。

例1,String类原本只能做单纯的文本,扩展:增加文本样式,如粗体、斜体、下划线等。

class StyledString extends String //extends是扩展关键字

{

void setUnderlined(boolean underline){//参数为True/False,给出是否要划线的状态参数设置

……

}

void setItalics(boolean italic){

……

}

}

这里只添加了两个新的method,String原有的方法都能继续沿用。

例2,继承后,添加新的特性(这里是方法)

class Robot{

void talk(String phrase){

...

}}

class TranslationRobot extends Robot{

void translate(String phrase){

this.talk(phrase.replaceAll("a",substitute));//在这里复用talk, 在传入参数处中间添加了新方法 - replaceall

}}

使用延伸的新方法

public static void main(String args[])

{

StyledString message = new StyleString("Hello");//初始化新的字符串

message.setUnderlined(true);

message.setItalics(true);//设置为要求进行下划线、斜体的操作

System.out.println(message);

}

覆写 (Overriding)

重载:基于父类旧方法 + 添加新特性到子类,产生“新“方法,就是重载。

class Robot{

...

void charge(float amount){

System.out.println(name+" charges.");

powerLevel += amount;

}}

class TranslationRobot extends Robot{//extends可自动收到父类所有特性,包括属性和方法,无需重新重复写

...

@Override //覆写时要像这样注释一个@Override,以防止破坏方法签名

void charge(float amount){

System.out.println(name+" charges double.");

powerLevel = powerLevel + 2*amount;//复用+修改,替代父类方法

}}

覆写Overriding——函数原型完全相同!改变的是:父类的方法函数体。方法只有细微差别(原来是充电,这里是双倍充电)。

如上面Robot例子中,函数原型一致——都是void charge(float amount), return为空,输入都是浮点型。

其overriding表现于函数体不同:println()里的内容,以及powerLevel的变化有细微差别!

区别:重载Overloading——仅函数名相同,函数原型不同:参数不同、return类型不同等。函数签名signature因为输入参数的数量、类型等不同而不同。与多态性有关。例:

public class Sum {

public int sum(int x, int y)

{

return (x + y);

}

public int sum(int x, int y, int z)

{

return (x + y + z);

}

public double sum(double x, double y)

{

return (x + y);

}

public static void main(String args[])

{

Sum s = new Sum();

System.out.println(s.sum(10, 20));

System.out.println(s.sum(10, 20, 30));

System.out.println(s.sum(10.5, 20.5));

}

}

无论覆写还是重载,方法名都一样。因此实际调用的方法,取决于实际执行的对象。

例如,定义对象:普通机器人Robot C, 翻译机器人TranslationRobot D。

那么C.charge ( 2f ) 和 D.charge ( 2f ) 采用的方法就是不同的。

方法链

复用父类的方法,并在结尾处添加一些额外的特性。例如:

public Sting toString()

{

String text = super.toString();//沿用父类方法,一路递归顺沿至最上层父类

if(isUnderlined) text = "\033[4m"+"\033[0m";

if(isItalics) text = "\033[3m"+"\033[0m"; //两个if()的函数体为额外添加的方法特性

return text;

}

多态性

输入的String种类可能不确定,可能是最普通的String,也可能是上面延伸得到的styledString。

要写适用于两种String的方法,需要更通用笼统的方法:

public void spellCheck(String text) ...

这种方法既适用于String数据类型的对象 (普通String),也适用于String型的子类 (即延伸得到的 styledString)。

父类和子类有同名的方法,父类的可以无细节,只有一个抽象的函数名;

创建父类的一个范例变量,可用于存其衍生的下面任意子类型变量。

利用父类范例的多态性,父子类的同名方法(但细节上有些许差别),可以省去重复代码。

动态调度

public class Mammal {

...

public void makeNoise() {

System.out.println("Generic mammal sound");

}}

public class Dog extends Mammal{

public void makeNoise() {

System.out.println("woof woof");

}}

public class Lion extends Mammal{

public void makeNoise() {

System.out.println("grrrrrrr! roar");

}}

public class Dolphin extends Mammal{

public void makeNoise() {

System.out.println("squeek click");

}}

//下面是通过多态性使用动态调度方法

public class MammalPlanet {

public static void main(String [] args) {

Mammal [] mammalArrayObject = new Mammal[3];

mammalArrayObject[0] = new Lion();

mammalArrayObject[1] = new Dog();

mammalArrayObject[2] = new Dolphin();

for(Mammal mCurr : mammalArrayObject){

mCurr.stateAttributes();

mCurr.makeNoise();

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值