练习代码(四)多态

小白做课后习题,有不对的地方或者不好的地方多多包容。

1. 在基类Shapes.java中添加一个新方法,用于打印一条消息,但导出类中不要覆盖这个方法。请解释发生了什么。现在,在其中一个导出类中覆盖该方法,而在其他的导出类中不予覆盖,观察又有什么发生。最后,在所有的导出类中覆盖此方法。

import java.util.Random;
class Shape{
void draw(){}
void erase(){}
void say(){
System.out.println("Shape.say()");
}
}
class Circle extends Shape{
void draw(){
System.out.println("Circle.draw()");
}
void erase(){
System.out.println("Circle.erase()");
}
void say(){
System.out.println("Circle.say()");
}
}
class Triangle extends Shape{
void draw(){
System.out.println("Triangle.draw()");
}
void erase(){
System.out.println("Triangle.erase()");
}
void say(){
System.out.println("Triangle.say()");
}
}
class RandomShapeGenerator{
private Random rand = new Random();
public Shape get(){
switch(rand.nextInt(3)){
default:
case 1: return new Circle();
case 2: return new Triangle();
}
}
}
public class Shapes {
private static RandomShapeGenerator gen = new RandomShapeGenerator();
public static void main(String[] args){
Shape[] s = new Shape[6];
for(int i = 0; i < s.length; i++)
s[i] = gen.get();
for(int i = 0; i < s.length; i++){
s[i].say();
s[i].draw();
}
  }
}

输出结果:

Circle.say()
Circle.draw()
Circle.say()
Circle.draw()
Triangle.say()
Triangle.draw()
Triangle.say()
Triangle.draw()
Circle.say()
Circle.draw()
Circle.say()
Circle.draw()

2. 向Shapes.java中添加一个新的Shape类型,并在main()方法中验证:多态对新类型的作用是否与在旧类型中的一样。

import java.util.Random;
class Shape{
void draw(){}
void erase(){}
void say(){
System.out.println("Shape.say()");
}
}
class Circle extends Shape{
void draw(){
System.out.println("Circle.draw()");
}
void erase(){
System.out.println("Circle.erase()");
}
void say(){
System.out.println("Circle.say()");
}
}
class Square extends Shape{
void draw(){
System.out.println("Square.draw()");
}
void erase(){
System.out.println("Square.erase()");
}
void say(){
System.out.println("Square.say()");
}
}
class Triangle extends Shape{
void draw(){
System.out.println("Triangle.draw()");
}
void erase(){
System.out.println("Triangle.erase()");
}
void say(){
System.out.println("Triangle.say()");
}
}
class RandomShapeGenerator{
private Random rand = new Random();
public Shape get(){
switch(rand.nextInt(3)){
default:
case 1: return new Circle();
case 2: return new Triangle();
}
}
}
public class Shapes {
private static RandomShapeGenerator gen = new RandomShapeGenerator();
public static void main(String[] args){
Shape[] s = new Shape[6];
Shape a = new Square();
a.draw();
a.erase();
a.say();
for(int i = 0; i < s.length; i++)
s[i] = gen.get();
for(int i = 0; i < s.length; i++){
s[i].say();
s[i].draw();
}
  }
}

输出结果:

Square.draw()
Square.erase()
Square.say()
Circle.say()
Circle.draw()
Circle.say()
Circle.draw()
Circle.say()
Circle.draw()
Circle.say()
Circle.draw()
Triangle.say()
Triangle.draw()
Triangle.say()
Triangle.draw()

3.创建Rodent(啮齿动物):Mnouse(老鼠),Gerbil(鼹鼠),Hamster(大颊鼠),等等这样一个的继承层次结构。在基类中,提供对所有的Rodent都通用的方法,在导出类中,根据特定的Rodent类型覆盖这些方法,以便它们执行不同的行为。创建一个Robent数组,填充不同的Rodent类型,然后调用基类方法,观察发生什么情况。

import java.util.Random;


class Rodent{
void foot(){}
void say(){}
}
class Mouse extends Rodent{
void foot(){
System.out.println("four");
}
void say(){
System.out.println("ZZ");
}
}
class Gerbil extends Rodent{
void foot(){
System.out.println("doubletwo");
}
void say(){
System.out.println("CC");
}
}
class Hamster extends Rodent{
void foot(){
System.out.println("twodouble");
}
void say(){
System.out.println("BB");
}
}
public class Rodents {
static Random rand = new Random();
public static Rodent get(){
switch(rand.nextInt(3)){
default:
case 0: return new Mouse();
case 1: return new Gerbil();
case 2: return new Hamster();
}
}
public static void main(String[] args){
Rodent[] rodent = new Rodent[4];
for(int i = 0; i < rodent.length; i++)
rodent[i] = get();
for(int i = 0; i < rodent.length; i++){
rodent[i].foot();
rodent[i].say();
}
}
}

输出结果:

twodouble
BB
four
ZZ
doubletwo
CC
twodouble
BB

4.修改练习3,使之能够演示基类和导出类的初始化顺序。然后向基类和导出类中添加成员对象,并说明构建期间初始化发生的顺序。

import java.util.Random;


class Rodent{
static int z ;
private String father = "father";
Rodent(){
System.out.println(father);
}
void foot(){}
void say(){}
}
class Mouse extends Rodent{
static int i ;
private String son = "son";
Mouse(){
System.out.println(son);
}
void foot(){
System.out.println("four");
}
void say(){
System.out.println("ZZ");
}
}
class Gerbil extends Rodent{
static int j ;
private String daught = "daught";
Gerbil(){
System.out.println(daught);
}
void foot(){
System.out.println("doubletwo");
}
void say(){
System.out.println("CC");
}
}
public class Rodents {
public static void main(String[] args){
Rodent m = new Mouse();
Rodent g = new Gerbil();
}
}

输出结果:

father
son
father
daught

5.创建一个包含两个方法的基类。在第一方法中可以调用第二个方法。然后产生一个继承自该基类的导出类,且覆盖基类中的第二个方法。为该导出类创建一个对象,将它向上转型到基类型并调用第一个方法,解释发生的情况。

class A{
void a(){
b();
System.out.println("World");

}
void b(){
System.out.print("Hello");
}
}
public class C extends A{
void b(){
System.out.print("Java");
}
    public static void main(String[] args){
    A a = new C();
    a.a();
}
}

输出结果:

JavaWorld

6.创建一个基类,让它包含抽象方法print(),并在导出类中覆盖该方法。覆盖后的方法版本可以打印导出类中定义的某个整型变量的值。在定义该变量之处,赋予它非零值。在基类的构造器中调用这个方法。现在,在main()方法中,创建一个导出类对象,然后调用它的print()方法。

abstract class A{
A(){
print();
}
   abstract void print();
}
public class C extends A{
private static int i = 123;
void print(){
System.out.println(i);
}
    public static void main(String[] args){
    C c = new C();
    c.print();
}
}

输出结果:

123
123

7.创建一个Starship类,包含一个AlertStatus引用,此引用可以指示三种不同的状态。纳入一些可以改变这些状态的方法。

import java.util.Random;


class AlertStatus{
void say(){}
}
class Happy extends AlertStatus{
void say(){
System.out.println("Happy");
}
}
class Sad extends AlertStatus{
void say(){
System.out.println("Sad");
}
}
class Angry extends AlertStatus{
void say(){
System.out.println("Angry");
}
}
public class Starship {
public static AlertStatus change(){
Random rand = new Random();
switch(rand.nextInt(2)){
default:
case 0: return new Sad();
case 1: return new Angry();
}
}
public static void main(String[] args){
AlertStatus status = new Happy();
status.say();
status = change();
status.say();
}
}

输出结果:

Happy
Sad

或者:

Happy
Angry

8.创建一个不包含任何方法的抽象类,从它那里导出一个类,并添加一个方法。创建一个静态方法,它可以接受指向基类的引用,将其向下转型到导出类,然后再调用该静态方法。在main()中,展现它的运行情况。然后,为基类中的方法加上abstract 声明,这样就不再需要进行向下转型。

未加abstract之前:

abstract class A{
}
public class C extends A{
public void print(){
System.out.println("Java");
}
public static void stright(A a){
((C)a).print();
}
    public static void main(String[] args){
    A a = new C();
    stright(a);
}
}

输出结果:

java

加入abstract之后:

abstract class A{
abstract  void print();
}
public class C extends A{
public void print(){
System.out.println("Java");
}
public static void stright(A a){
((C)a).print();
a.print();
}
    public static void main(String[] args){
    A a = new C();
    stright(a);
}

输出结果:

Java

Java

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值