-1

我对扩展课程有些困惑。我认为解释我想做的最好的方法是使用一些骨架代码:

abstract class Player
{
  public int solve()
  { // One method of solving problem
  }
}

class otherPlayer extends Player
{ 
  public char solve(int num)
  { //Different method of solving same problem
  }
}

// I suspect this is a wrong way to create Player
Player first = new otherPlayer;
// Because this gives me an error...
first.solve(5)'
// And this uses the super class's method of solving problem
first.solve();
// I don't want to do this though...
otherPlayer first = new otherPlayer;

// Because I actually define the Players in a method
// that returns a type Player():
private Player genPlayer()
{ // Take input from keyboard
  Player newPlayer;
  if (specific set of answers)
    newPlayer = new otherPlayer();
  else newPlayer = new Player();

  return newPlayer;
}

我对扩展类的理解是有限的。如果我说“TypeA var = new TypeB”,而 TypeB 扩展了 TypeA,那么 var 似乎只能访问 TypeA 类中的方法。它是做什么的,那么说它是一个新的TypeB?为什么这甚至是实例化变量的合法方式?你会如何建议我重组这个程序以便让它工作(我宁愿保留这个方法,这样我每次创建播放器时都不必弄得一团糟)?

我真的只是想知道如何创建一个扩展类,就好像我是一个知道自己在做什么的人一样。

4

7 回答 7

1

的重点TypeA a = new TypeB()是对合同进行编程。这意味着您可以更改TypeB为任何其他类型,extends TypeA并保证不必更改任何其他代码行。

于 2013-02-08T18:21:24.203 回答
1

您需要执行以下操作:

abstract class Player {
    abstract void solve(int num);
}

class OtherPlayer extends Player {
    void solve(int num) {
        //...
    }
}

也就是说,要通过 type 的变量调用方法Player,至少必须在该类上声明其签名 - 并且必须在所有子类中实现。无法使用超类类型的变量调用子类中可能存在或不存在的方法。

想象一下你可以这样做:

class Player {
    // ...
}

class FooPlayer extends Player {
    void solveInt(int num) { 
        // ... 
    }
}

class BarPlayer extend Player {
    void solveString(String s) {
        // ...
    }
}

Player[] players = new[] {new FooPlayer(), new BarPlayer()};
// this is the sort of code you want to work
for (Player p : players) {
    p.solveInt(123);
}

调用该方法时应该发生什么BarPlayer?如您所见,允许这样做没有多大意义。

虽然明确地做不是很有用Player player = new FooPlayer(),但它确实让您不必知道Player值的确切子类型。忽略了查看子类型之间不同的方法的要点——多态性的要点是相同的方法(即具有相同的签名)在子类之间以不同的方式实现:

class Player {
    abstract String greet();
}

class EnglishPlayer extends Player {
    String greet() {
        return "Hello";
    }
}

class JapanesePlayer extends Player {
    String greet() {
        return "Konnichi wa";
    }
}
于 2013-02-08T18:26:09.730 回答
0

首先,您在实例化语法中遇到错误。应该是new otherPlayer()。java中的类也应该大写。我假设代码在一个方法中,否则它不会编译。最后,回答您为什么要扩展一个类的问题,如果 otherPlayer 有自己的实现solve()(无参数),那么将调用哪个方法将取决于您使用的实例化,而不是变量类型。换句话说,first.solve() 将在 otherPlayer 中调用该方法,而不是在 player 中。

于 2013-02-08T18:22:55.153 回答
0

扩展是关于超类和子类的。

如果 typeA 是 typeB 的子类,那么你可以说

typeA继承了typeB,typeA继承了typeB的所有方法

它只有一种方式,有点像孩子可以从父母那里继承特征,但父母不会从孩子那里继承任何东西

如果您希望子类中的方法与父类中的方法行为不同,只需编写一个具有相同名称/参数的新方法。子类方法自动覆盖超类方法。那么,如果你想使用方法的超类版本,你可以使用 super 关键字

于 2013-02-08T18:23:25.913 回答
0

继承是在你扩展一个类时发生的事情,你需要找出你想要在你的类和子类中使用的通用方法,并在你的子类中定义任何替代方法。

查看更多信息:http ://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

于 2013-02-08T18:23:30.650 回答
0

您将“first”声明为引用 otherPlayer 对象的 Player 引用。这是合法的,但如果你想要 otherPlayer 行为,你将不得不 typecat 'first': ((otherPlayer)first).solve(5)

于 2013-02-08T18:25:49.423 回答
0

首先,你不能实例化抽象类,所以你不能编码newPlayer = new Player();

ClassA a = new ClassB();然后,只要 ClassB 是 ClassA 的子类并且 ClassB 不是抽象类,写类似的东西是完全合法的。

如果您在 ClassB 中有一个方法覆盖 ClassA 的方法,该方法的调用取决于对象的动态类型,实际上是您用于实例化该对象的类型,这称为多态性。网上有很多关于这方面的资料(面向对象编程和 Java),但我认为一个很好的起点是 Bruce Eckel 的 Thinking in Java 一书,他在他的网站上免费提供了第三版(http ://www.mindview.net/Books/TIJ/)。

于 2013-02-08T18:50:36.810 回答