我正在创建一个拥有不同类型广场的垄断游戏。
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();
我如何更改它或能够调用子类方法?
答案 0 :(得分:2)
我认为board.getSquare()
会返回Square
,Square
没有任何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