关于Java中扩展类的困惑

时间:2013-02-08 18:18:09

标签: java class abstract extends

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

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?为什么这甚至是实例化变量的合法方式?你会如何推荐我重组这个程序,这样我才能使它工作(我更喜欢保留这个方法,所以每次创建一个播放器时我都不必弄得一团糟)?

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

7 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您需要执行以下操作:

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

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

也就是说,要通过类型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";
    }
}

答案 2 :(得分:0)

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

答案 3 :(得分:0)

扩展是关于超类和子类。

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

typeA扩展了typeB,而typeA将继承typeB

的所有方法

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

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

答案 4 :(得分:0)

继承是在扩展类时发生的事情,您需要在类和子类中找出所需的常用方法,并在子类中定义任何替换。

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

首先,您无法实例化抽象类,因此无法对newPlayer = new Player();进行编码。

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

如果你在ClassB中有一个方法来覆盖ClassA的方法,那么调用哪个方法取决于实际上用于实例化该对象的类型的对象的动态类型,这称为多态。网上有很多关于这个(面向对象的编程和Java)的资料,但我认为一个很好的起点是,Bruce Eckel撰写的Thinking in Java一书,他在他的网站免费提供第三版({ {3}})。

相关问题