如何基于String创建新类型的对象?

时间:2017-05-06 18:23:33

标签: java class oop casting

第一次在这里发帖。刚刚开始学习Java和编码,所以请耐心等待我!

所以这里有几节课。水果类,有2个子类 - 橙色和西瓜。

public class Fruit {
    String name;
    String size;

    public Fruit() {
        this.name = "Fruit";
        this.size = "";
    }

    public String getName() {
        return this.name;
    }

    public String getSize() {
        return this.size;
    }
}

class Orange extends Fruit {
    public Orange() {
        this.name = "Orange";
        this.size = "Small";
    }
}

class Watermelon extends Fruit {
    public Watermelon() {
        this.name = "Watermelon";
        this.size = "Large";
    }
}

我还有一个Crate类,我想存储Fruit Objects。但是,我希望它根据传递给构造函数的String来存储特定对象。

public class Crate {
    Fruit f = new Fruit();

    public Crate(String fruitType) {
        if (fruitType == "Orange") {
            f = (Orange)f;
        } else {
            f = (Watermelon)f;
        }
    }

    public String getFruitName() {
        String s = f.getName();
        return s;
    }
}

试图像这样向下转发给我一个错误。我的问题是如何根据传递给构造函数的内容完成向Crate对象添加某个Fruit子类?

编辑:谢谢大家的建议。做出改变建议,效果很好!

7 个答案:

答案 0 :(得分:4)

最简单的方法是只看String中的内容并使用new

if ("Orange".equals(fruitType)) {
    f = new Orange();
} else if ("Watermelon".equals(fruitType)) {
    f = new Watermelon();
}

(您也可以使用switch代替if...else if。)

你也可以将Fruit传递给构造函数,这样可以简化事情:

class Crate {
    Fruit fruit;

    Crate(Fruit fruitToHold) {
        this.fruit = fruitToHold;
    }
}

有些人会告诉你,你可以使用反射来创建Fruit而且这是真的,但如果你是初学者,那么你应该做的不是什么。

答案 1 :(得分:1)

你不能把一个类投射到它不是的东西上。由于您致电new Fruit(),因此它只是一个水果,因此您无法转为OrangeWatermelon

相反,您必须创建相应类型的对象。

此外,您绝不应使用==来比较String值。始终使用equals()

public class Crate {
    Fruit f;

    public Crate(String fruitType) {
        if (fruitType.equals("Orange")) {
            f = new Orange();
        } else {
            f = new Watermelon();
        }
    }
}

答案 2 :(得分:1)

投射不会改变对象的类型!

您只能将变量强制转换为引用对象已经存在的类型。

在您的示例中,变量^((https?|ftp|smtp):\/\/)?(www.)?[a-z0-9\-]+(\.[a-z\-]{2,}){1,3}(#?\/?[a-zA-Z0-9\-#]+)*\/?(\?[a-zA-Z0-9-_\-]+=[a-zA-Z0-9-%\-]+&?)?$ 中的对象的类型为fruitType。 它与String FruitOrange无关。因此,演员阵容失败了。

您可以做的是创建所需类型的 new 对象:

Watermellon

问题是:你不应该在构造函数中做这样的事情。此外,将字符串public Crate(String fruitType) { if (fruitType == "Orange") { f = new Orange(); } else { f = new Watermelon(); } } 进行比较也是一个坏主意,因为另一个答案和评论建议。

答案 3 :(得分:0)

==测试引用相等性(它们是否是同一个对象)。

String s1="Orange";
String s2="Orange";
if(s1==s2) ===> true

(s1 == s2)===>真

                   String Pool
s1 -----------------> "Orange" <-----------------s2

if(s1 == s3)===&gt;假

            String Pool
"Orange" <-------------------- s1

               Heap
"Orange" <-------------------- s3

您需要使用字符串equals方法

if ("Orange".equals(fruitType)) {
    f = new Orange();
} else if ("Watermelon".equals(fruitType)) {
    f = new Watermelon();
}

答案 4 :(得分:0)

== 运算符无法比较字符串,因为它基本上是比较整个对象,包括它的内存位置。这基本上意味着只有在被比较的两个字符串基本上是同一个实例时它才会返回tru。要比较Java中的2个字符串,可以使用.equals(string2)方法。

str1.equals(str2); 

仅比较2个字符串的值

答案 5 :(得分:0)

这么多答案,都缺少一个核心点:

Java是一种静态类型的语言。在字符串的基础上执行所有操作是Java的方法。您尝试避免此类代码!

换句话说:你的第一个错误就是创造那些不同的课程,并随身携带一个名字&#34;串。你可以这样做:

abstract class Fruit {
  @Override
  public final String toString() {
    return getClass().getSimpleName() + getSize();
  }

  abstract String getSize();

代替。这将确保任何水果的字符串表示只是给出(短)类名(没有包信息)以及getSize()的子类实现返回。

你可以使用它:

class Orange extends Fruit {
  private String size;
  Orange(String size) { this.size = size; };
  String getSize() { return size; }

对于橘子,可以有不同的尺寸;还

class Apple extends Fruit {
  String getSize() { return "always the same"; }

在我的示例中使用相同的大小!

对于创建对象,您更喜欢使用工厂方法,例如:

Fruit createByName(String fruitName) {
  switch (fruitName) {
    case "Orange": return new Orange();
    case ...
    default: throw new IllegalArgumentException("unknown fruit: " + fruitName);
  }
}

答案 6 :(得分:0)

"Orange" == "Orange"如果两个字符串指向同一个内存位置,则此表达式会给出true。这意味着两者都引用相同的 String 对象。

但在比较给定对象的后,equal()方法将会返回。

参考以下示例,

"ss"=="ss"                       //true 
"ss" == new String("ss")         //false
"ss".equals("ss")                //true
"ss".equals(new String("ss"))    //true