子类和超类方法

时间:2015-11-05 15:24:48

标签: java inheritance subclass superclass

我正在创建一个拥有不同类型广场的垄断游戏。 Square超类PropertySquare子类

我已经创建了一个循环来掷骰子并将玩家移动到不同的方格。方块在数组列表中,我可以在它们上调用超类方法。但是,即使将方块设置为更具体的类型(square的子类),我也无法在它们上调用子类方法。

这就是我在棋盘类中初始化方块的方法。

private static final ArrayList<Square> squares = new ArrayList<Square>(40);
squares.add(1, new PropertySquare("Old Kent Road", 1, 60, "Brown"));
board.getSquare(pos).getName());

getName是超类广场中的一种方法。但是,即使广场是属性类型,我也无法调用PropertySquare类中的方法,例如getPrice();

我如何更改它或能够调用子类方法?

5 个答案:

答案 0 :(得分:2)

我认为board.getSquare()会返回SquareSquare没有任何getPrice()方法,因此您无法通过对象调用getPrice()声明为Square,即使实例实际上是PropertySquare(又名polymorphism)。为此,您必须首先转换为特定的子类。例如:

final Square square = board.getSquare(pos);
if (square instanceof PropertySquare) {
    ((PropertySquare)square).getPrice();
}

答案 1 :(得分:0)

注意:我将在更一般的意义上回答这个问题,我意识到并非所有的垄断广场都有价格......但问题本身,在代码中,可以通过两种方式解决。

如果您的所有商品都有价格,您可能想要使用&#34;抽象&#34;基类。

然后将超类中的方法放入

protected abstract int getPrice();

并在您的子类中实现它。

所以你可以有子类,例如undevelopedSquare,propertySquare,gardenSquare等。

但是,在Monopoly的情况下,如果只有propertySquare实例有getPrice,你应该使用

if (square instanceOf PropertySquare) {
    price = ((PropertySquare)square).getPrice();
}

NB2:您还拥有&#34; utilitySquare&#34;如Waterworks,它会在价格旁边具有不同的属性(即使您可以购买,也无法在实用程序上建立酒店)

所以在这种情况下,接口可能更合适,例如:

interface PlayableSquare -> Generic square things, you can land on one for instance

interface SaleableSquare -> has pricing etc

interface BuildableSquare -> can build hotels

然后将你的通用作为

private static final ArrayList<? extends Square> squares

PropertySquare将是:

public class PropertySquare extends AbstractSquare implements SaleableSquare, BuildableSquare

Abstract类实现&#34; PlayableSquare&#34;。虽然这可能是一个步骤太远,因为它几乎只是一个标记界面。

你可以使用instanceOf来检查每个接口的实现,即如果一个实用程序有你想要调用的不同方法。

答案 2 :(得分:0)

您应该将Generics与ArrayList一起使用。 如果您的列表只包含<?php $wp_database = new mysqli("yourhost", "yourusername", "yourpasssword", "yourdatabase"); /* check connection */ if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } // Here's how you get all the posts. Adjust table names to suit. $sql = "SELECT * FROM `wp_posts` WHERE `post_status` LIKE 'publish' AND `post_type` LIKE 'post'"; $result = mysqli_query($wp_database, $sql); $posts = mysqli_fetch_all($result, MYSQLI_ASSOC); mysqli_free_result($result); foreach ($posts as $post): ?> <div> <?php print_r($post); ?> </div> <?php endforeach; // And here's how you get an individual image url. $post_id = 1181; // Your post ID here $sql = "SELECT `guid` FROM `wp_posts` WHERE `id` IN (SELECT `meta_value` FROM `wp_postmeta` WHERE `meta_key` LIKE '_thumbnail_id' AND `post_id` = $post_id)"; $result = mysqli_query($wp_database, $sql); $images = mysqli_fetch_all($result, MYSQLI_ASSOC); mysqli_free_result($result); foreach ($images as $image): ?> <div> <?php print_r($image); ?> </div> <?php endforeach; ?> 类型,请按以下步骤操作:

PropertySquare

然后列表将返回private static final ArrayList<PropertySquare> squares = new ArrayList<>(40); squares.add(1, new PropertySquare("Old Kent Road", 1, 60, "Brown")); 类型的对象。

如果列表可以包含任何类型的方块,请执行以下操作:

PropertySquare

代码中的问题是您的对象是Square类型,并且不知道任何子类的方法。所以你必须做一个类型转换。

答案 3 :(得分:0)

你可以在一组ifs中处理着陆广场:

if (square instanceof PropertySquare) {
    ((PropertySquare)square).getPrice();
}else if(square instanceof PrisonSquare) {
//do nothing 
}//etc..

答案 4 :(得分:0)

您声明的ArrayList绑定到Square,这意味着您在与任何项目进行交互时将拥有Square个对象和Square引用的集合,尽管它在运行时它是一个子类的实例。这被称为多态性。

由于引用的类型为Square,因此Java知道的唯一方法是Square中声明的方法和任何其他继承的方法。为了能够调用子类的方法,您需要检查引用是否指向PropertySquare的实例,然后向下转换PropertySquare的引用。您之后说,没关系,我知道它是PropertySquare的一个实例,因此我可以安全地调用getPrice()中声明的PropertySquare方法。

if (square instanceof PropertySquare) {
    ((PropertySquare)square).getPrice();
}

或者,您可以查看实例类名称:

square.getClass().getSimpleName();  // Would just give you PropertySquare
square.getClass().getCanonicalName(); // Would give you the fully qualified name e.g. com.foo.bar.PropertySquare

欲了解更多信息:

https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html