gpt4 book ai didi

java - 无法使用多态访问具体类的唯一属性

转载 作者:搜寻专家 更新时间:2023-11-01 03:59:28 24 4
gpt4 key购买 nike

我正在使用工厂模式在 java version "1.7.0_60" 中创建不同连接的对象

我面临的问题是每个具体类都将具有该特定类的唯一属性。由于工厂在返回具体类的实例时将使用多态性,因此我无法访问唯一属性。即 getHostType() 仅对 SqlServerConnection 是唯一的。

我所做的解决方法是在父类(super class)中声明 getHostType() 抽象并在每个具体类中实现它。但是,我真的不想那样做,因为我添加的具有独特属性的具体类越多,我就必须在父类(super class)中包含越多的抽象方法,然后在每个具体类中实现它们。

我想保留我的工厂模式和抽象父类(super class)。我只是想知道是否有任何其他方法可以代替父类(super class)中的抽象方法?我可以包含任何设计模式来解决这个问题吗?

public abstract class Connection {
private int port;
private int ipAddress;

public Connection() {}

public String description() {
return "Generic";
}

/* Implement in every concrete class, even if the concrete type doesn't have that property */
public abstract int getHostType();
}

public class SqlServerConnection extends Connection {
private int sqlHostType;

public SqlServerConnection() {
sqlHostType = 5060;
}

@Override
public String description() {
return "Created a Sql Server connection type";
}

@Override
public int getHostType() {
return sqlHostType;
}
}

public class OracleConnection extends Connection {
public OracleConnection() {}

@Override
public String description() {
return "Created an Oracle connection type";
}
}

final public class ConnectionFactory {
protected String mType;

public ConnectionFactory(String type) {
mType = type;
}

/* Create the connection we want to use */
public Connection createConnection() {
if(mType.equals("Oracle")) {
return new OracleConnection();
}
else if(mType.equals("SQLServer")) {
return new SqlServerConnection();
}
else {
return null;
}
}
}

public class TestConnection {
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory("SQLServer");
Connection conn = factory.createConnection();

conn = factory.createConnection();
System.out.println(conn.description());
/* need to access the getHostType() */
System.out.println(conn.getHostType());
}
}

最佳答案

您应该看看访问者模式。您需要声明一个接口(interface) ConnectionVisitor 并为层次结构中的每个连接类添加一个方法访问。

public interface ConnectionVisitor {

public int visit (Connection connection);
public int visit (SqlServerConnection sqlconnection);
public int visit (OracleConnection oracleConnection)
}

现在您需要在基类连接中添加一个接受方法,该方法接受一个 ConnectionVisitor,然后对其调用访问。您的新连接类看起来像

public abstract class Connection {
private int port;
private int ipAddress;

public Connection() {}

public String description() {
return "Generic";
}

public int accept(ConnectionVisitor visitor){
return visitor.visit(this);
}

请注意,accept 方法执行双重分派(dispatch)。它根据调用它的对象和传递给此方法的参数进行分派(dispatch)。这是访问者模式的核心。

然后您可以实现 ConnectionVisitor 接口(interface)来定义任何新功能,而无需更改您的基类。

class   DemoVisitor implements ConnectionVisitor{
public int visit(Connection connection){
System.out.println("Visiting Connection");
return 1;
}

public int visit(SqlServerConnection sqlServerConnection){
System.out.println("Visiting SqlServerConnection");
return 1;
}

public int visit(OracleConnection oracleConnection){
System.out.println("Visiting Oracle Connection");
return 1;
}

在您的 TestConnection 类中,您可以简单地创建一个新的连接对象,然后对该对象调用 accept 方法并传递一个访问者对象。

public class TestConnection {
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory("SQLServer");
Connection conn = factory.createConnection();

conn = factory.createConnection();
System.out.println(conn.description());
ConnectionVisitor visitor = new DemoVisitor();
System.out.println(conn.accept(visitor));
}

因此,现在任何特定于子类的功能都不能驻留在连接类层次结构中,而必须在新访问者中实现。

请注意,此模式不适合您的场景。这种模式的限制之一是访问者接口(interface)中所有方法的返回类型必须相同。这种模式可能适合也可能不适合您的需要,但值得研究您的情况。您可能需要修改此模式以满足您的需要。这就是模式的全部意义在于研究一些常见的解决方案,然后修改这些解决方案以适应您的问题。

关于java - 无法使用多态访问具体类的唯一属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24778774/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com