简体   繁体   English

Java:如何通过调用父类的子类获取对象

[英]Java: How to get the object of a subclass by calling it's parent class

import java.util.*;
import java.lang.*;
import java.io.*;

class mainA {
   private mainA obj;

public mainA(int type) {
  System.out.println("accessing mainA");
  switch(type) {
     case 1:
        obj = new mysql();
        break;

     case 2:
        obj = new mssql();
        break;

     default:
        break;
   }
  }
}

class mysql extends mainA {
  public void printme() {
    System.out.println("accessing mysql");
  } 
}

class mssql extends mainA {
  public void printme() {
    System.out.println("accessing mssql");
  }
}

class C2 extends mainA {

   public C2() {
      super();
   }
   public static void main(String args[]){
      Object b = new C2();
      b.printme();
   }
 }

I need to achieve the following scenario. 我需要实现以下方案。 It would be great if someone can help me out. 如果有人可以帮助我,那就太好了。 I'm trying to create a common API library set which can be scaled to as many backend databases as possible. 我正在尝试创建一个通用的API库集,该库集可以扩展到尽可能多的后端数据库。

The idea is to create an object of C2, which in turn would return the value of either mysql/mssql based on the dbtype. 这个想法是创建一个C2对象,该对象又将基于dbtype返回mysql / mssql的值。 The type parameter can be obtained from any where in the code. 可以从代码中的任何位置获取type参数。 mainA is the super class which consists of config params. mainA是由配置参数组成的超类。 Type can be obtained here as well. 类型也可以在这里获得。 The problem here is that I'm stuck with not being able to get the object of mysql/mssql from C2. 这里的问题是我无法从C2获取mysql / mssql的对象。 The ideal situation would be to create an object of C2 which refers to mainA that gets the type and inits either mssql/mysql. 理想的情况是创建一个引用mainA的C2对象,该对象获取类型并启动mssql / mysql。 C2.printme must call the db class which was specified in the type. C2.printme必须调用在类型中指定的db类。

Would generic classes be of any help here? 泛型类在这里有帮助吗?

you can have an instanceof test to cast the object but it is lame as you would have to change your code if you are adding a new type of DB object. 您可以有一个instanceof测试来强制转换对象,但这很la脚,因为如果要添加新类型的DB对象,则必须更改代码。

You can have a good interface and make the subclasses implement it so that you can call through your interface without caring about the actual implementation object. 您可以拥有一个良好的接口并使子类实现它,以便您可以通过接口进行调用而无需关心实际的实现对象。

Coding to Interface is what you should be doing. 对接口进行编码是您应该做的。

You've got some work ahead of you. 您还需要做一些工作。 You'll want to read up on interfaces. 您将需要阅读接口。 In your example, you can do something like the following (it's a bit silly in the real world). 在您的示例中,您可以执行以下操作(在现实世界中这有点愚蠢)。

Let's call our interface Printable.java (by convention, starts with either the capital letter "I" or ends in "-ible", "able," etc). 我们将其称为Printable.java接口(按照约定,以大写字母“ I”开头或以“ -ible”,“ able”等结尾)。 I wouldn't really call it Printable, but for the purpose of this example: 我不会真正将其称为Printable,但出于此示例的目的:

public interface Printable {
   public void logDatabaseType();
}

Your parent class (we can make it abstract so that it cannot be created directly without an underlying implementation): 您的父类(我们可以使其抽象化,以便没有基础实现就不能直接创建它):

public abstract class Database implements Printable {
    @Override
    public void logDatabaseType() {
        System.out.println("logDatabaseType()");
    }
}    

Your subclasses: 您的子类:

public class MySQL extends Database implements Printable {
    @Override
    public void logDatabaseType() {
       System.out.println("Accessing MySQL");
    }
}

public class MicrosoftSQL extends Database implements Printable {
    @Override
    public void logDatabaseType() {
       System.out.println("Accessing MSSQL");
    }
}

In your test class (you should try to get your feet wet with JUnit as early as possible): 在测试课中(您应该尽早使用JUnit进行尝试):

 public class DatabaseLogTest {

   @Test
   public void printDatabaseType() {
       //programming by interface
       Printable printable = new MySql();         
       printable.logDatabaseType();

       printable = new MicrosoftSQL();
       printable.logDatabaseType();

       //then later you can do 
       //someMethod(printable);
       //and the printable object will retain whatever was instantiated
       //and someMethod will be blissfully ignorant of the actual implementation
    } 

} }

@Override is important because it tells your IDE and the developer that you're overriding an implementation and the IDE will spit out errors if the implied contract is not met. @Override很重要,因为它告诉您的IDE和开发人员您正在重写实现,并且如果不符合隐含的约定,则IDE将吐出错误。 You should have this whenever you're overriding. 每次覆盖时都应具有此功能。

You'd also want to use a logger (eg, SLF4j over Log4J or logback) rather than System.out.println() method calls. 您还希望使用记录器(例如,通过Log4J或Slog4J的SLF4j)而不是System.out.println()方法调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM