Java 方法在泛型返回对象中不可用

Java 方法在泛型返回对象中不可用,java,Java,我试图从返回的对象obj访问方法GetDatbaseName(),但返回的错误是该方法不可用 但是,当我键入obj时,它正在工作 String name = ((Oracle)obj).GetDatabaseName(); 如何处理这个问题?比如我不能为每个返回类型进行类型转换,比如Oracle和MongoDB。还有更好的实现方法吗 // one class needs to have a main() method public class HelloWorld { // argumen

我试图从返回的对象
obj
访问方法
GetDatbaseName()
,但返回的错误是该方法不可用

但是,当我键入
obj
时,它正在工作

String name = ((Oracle)obj).GetDatabaseName();
如何处理这个问题?比如我不能为每个返回类型进行类型转换,比如
Oracle
MongoDB
。还有更好的实现方法吗

// one class needs to have a main() method
public class HelloWorld
{
  // arguments are passed using the text field below this editor
  public static void main(String[] args)
  {
    Data dt = new Data("Oracle");
    Object obj = dt.GetObject();

    String name = obj.GetDatabaseName();

    System.out.println(name);
  }
}

public class Data
{
    public String _type;

    public Data(String type)
    {
      _type = type;
    }

    public Object GetObject()
    {
      Object obj = null;

      switch(_type)
      {
        case("Oracle"):

        obj = new Oracle("Test");

        break;

        case("MongoDB"):

        obj = new MongoDB("TestCollection");

        break;

      }

      return obj;
    }
}


public class Oracle
{
  public String _databaseName;

  public Oracle(String databaseName)
  {
    _databaseName = databaseName;
  }

  public String GetDatabaseName() { return _databaseName; }
}

public class MongoDB
{
  public String _collectionName;

  public MongoDB(String collectionName)
  {
    _collectionName = collectionName;
  }

  public String GetCollectionName() { return _collectionName; }
}

问题出现在以下几行:

Object obj = dt.GetObject();

String name = obj.GetDatabaseName();
就这些行而言,obj属于Object类型,它没有被调用的方法;因此,这是一个问题。这是因为Java是强类型的

要解决这个问题,您需要一个具有此方法的类型,或者使用反射。要使用具有此方法的类型,他们需要从的公共父级继承它,并从公共接口实现它。您还可以包装对象或一组其他备选方案

在您的情况下,公共接口似乎是最简单的方法。在这种情况下,每个类都应该实现该接口,而不是使用对象,您的引用将是该接口的类型

public Object GetObject()
将成为

public MyInterface GetObject()

会是

public class Oracle implements MyInterface
MyInterface将在其中声明该方法

public interface MyInterface {
    String GetDatabaseName();
}
注意Java约定,方法应该以小写开头

public interface MyInterface {
    String getDatabaseName();
}
在无法更改代码以实现这些方法的情况下,可以使用“instanceof”对类类型进行测试

name = (obj instanceof Oracle)?((Oracle)obj).GetDatabaseName():((MongoDB )obj).getCollectionName();

问题出现在以下几行:

Object obj = dt.GetObject();

String name = obj.GetDatabaseName();
就这些行而言,obj属于Object类型,它没有被调用的方法;因此,这是一个问题。这是因为Java是强类型的

要解决这个问题,您需要一个具有此方法的类型,或者使用反射。要使用具有此方法的类型,他们需要从的公共父级继承它,并从公共接口实现它。您还可以包装对象或一组其他备选方案

在您的情况下,公共接口似乎是最简单的方法。在这种情况下,每个类都应该实现该接口,而不是使用对象,您的引用将是该接口的类型

public Object GetObject()
将成为

public MyInterface GetObject()

会是

public class Oracle implements MyInterface
MyInterface将在其中声明该方法

public interface MyInterface {
    String GetDatabaseName();
}
注意Java约定,方法应该以小写开头

public interface MyInterface {
    String getDatabaseName();
}
在无法更改代码以实现这些方法的情况下,可以使用“instanceof”对类类型进行测试

name = (obj instanceof Oracle)?((Oracle)obj).GetDatabaseName():((MongoDB )obj).getCollectionName();

您应该考虑代码的设计。您需要使用基本的面向对象原则来解决这个问题。有几种方法可以解决您的问题,比如使用接口/泛型等。这里我举一个这样的例子

public class HelloWorld {

    public static void main(String[] args) {
        Data dt = new Data("Oracle");
        DataBase obj = dt.GetObject();
        String name = obj.getDatabaseName();
        System.out.println("Name : "+name);
    }
}

class Data {
    public String _type;

    public Data(String type) {
        _type = type;
    }

    public DataBase GetObject() {
        DataBase dataBase=null;
        switch (_type) {
        case "Oracle":
            dataBase = new Oracle(); 
            break;
        case "Mongo":
            dataBase = new MongoDb(); 
            break;

        }
        return dataBase;
    }
}

interface DataBase {
    String getDatabaseName();
}

class Oracle implements DataBase {
    public String getDatabaseName() {
        return "Oracle";
    }
}

class MongoDb implements DataBase {
    public String getDatabaseName() {
        return "Mongo";
    }
}
编辑:

这是另一种解决你问题的方法。我相信这种方法可能会解决你的问题

public class HelloWorld {

    public static void main(String[] args) {
        Data<Oracle> dt = new Data<Oracle>("Oracle");
        Oracle obj = dt.getObject();
        String name = obj.getDatabaseName();
        System.out.println("Name : "+name);
    }
}

class Data<T> {
    public String _type;

    public Data(String type) {
        _type = type;
    }

    public T getObject() {
        Object dataBase=null;
        switch (_type) {
        case "Oracle":
            dataBase = new Oracle(); 
            break;
        case "Mongo":
            dataBase = new MongoDb(); 
            break;

        }
        return (T)dataBase;
    }
}


class Oracle  {
    public String getDatabaseName() {
        return "Oracle";
    }
}

class MongoDb {

}
公共类HelloWorld{
公共静态void main(字符串[]args){
数据dt=新数据(“Oracle”);
Oracle obj=dt.getObject();
String name=obj.getDatabaseName();
System.out.println(“名称:”+Name);
}
}
类数据{
公共字符串类型;
公共数据(字符串类型){
_类型=类型;
}
公共T getObject(){
对象数据库=null;
开关(U型){
案例“甲骨文”:
数据库=新Oracle();
打破
“Mongo”案:
数据库=新的MongoDb();
打破
}
返回(T)数据库;
}
}
甲骨文类{
公共字符串getDatabaseName(){
返回“甲骨文”;
}
}
MongoDb类{
}

您应该考虑代码的设计。您需要使用基本的面向对象原则来解决这个问题。有几种方法可以解决您的问题,比如使用接口/泛型等。这里我举一个这样的例子

public class HelloWorld {

    public static void main(String[] args) {
        Data dt = new Data("Oracle");
        DataBase obj = dt.GetObject();
        String name = obj.getDatabaseName();
        System.out.println("Name : "+name);
    }
}

class Data {
    public String _type;

    public Data(String type) {
        _type = type;
    }

    public DataBase GetObject() {
        DataBase dataBase=null;
        switch (_type) {
        case "Oracle":
            dataBase = new Oracle(); 
            break;
        case "Mongo":
            dataBase = new MongoDb(); 
            break;

        }
        return dataBase;
    }
}

interface DataBase {
    String getDatabaseName();
}

class Oracle implements DataBase {
    public String getDatabaseName() {
        return "Oracle";
    }
}

class MongoDb implements DataBase {
    public String getDatabaseName() {
        return "Mongo";
    }
}
编辑:

这是另一种解决你问题的方法。我相信这种方法可能会解决你的问题

public class HelloWorld {

    public static void main(String[] args) {
        Data<Oracle> dt = new Data<Oracle>("Oracle");
        Oracle obj = dt.getObject();
        String name = obj.getDatabaseName();
        System.out.println("Name : "+name);
    }
}

class Data<T> {
    public String _type;

    public Data(String type) {
        _type = type;
    }

    public T getObject() {
        Object dataBase=null;
        switch (_type) {
        case "Oracle":
            dataBase = new Oracle(); 
            break;
        case "Mongo":
            dataBase = new MongoDb(); 
            break;

        }
        return (T)dataBase;
    }
}


class Oracle  {
    public String getDatabaseName() {
        return "Oracle";
    }
}

class MongoDb {

}
公共类HelloWorld{
公共静态void main(字符串[]args){
数据dt=新数据(“Oracle”);
Oracle obj=dt.getObject();
String name=obj.getDatabaseName();
System.out.println(“名称:”+Name);
}
}
类数据{
公共字符串类型;
公共数据(字符串类型){
_类型=类型;
}
公共T getObject(){
对象数据库=null;
开关(U型){
案例“甲骨文”:
数据库=新Oracle();
打破
“Mongo”案:
数据库=新的MongoDb();
打破
}
返回(T)数据库;
}
}
甲骨文类{
公共字符串getDatabaseName(){
返回“甲骨文”;
}
}
MongoDb类{
}

解决这个问题有两种方法,第一种方法是使用泛型
类,而第二种方法是使用
接口
,如果您知道类将具有相同的方法,第二种方法更好,而泛型方法是如果类具有不同的方法

一般方法
显然,
DatabaseName
对于接口来说是个坏名字,但它是两个类中唯一相同的方法,因此调用它是有意义的。接口的好处在于,只要知道方法名称,就不必对使用的类大惊小怪。

解决这个问题有两种方法,第一种是使用泛型
类,第二种是使用
接口,如果知道类将具有相同的方法,则第二种方法更好,而通用方法是如果类具有不同的方法

一般方法
显然,
DatabaseName
对于接口来说是个坏名字,但它是两个类中唯一相同的方法,因此调用它是有意义的。接口的好处在于,只要知道方法名称,就不必关心使用了什么