tags:

views:

257

answers:

5

I have different classes called English, Spanish, French, etc.:

Class English{
    String name = "English";
    String alias = "ENG";
}

Class French{
    String name = "French";
    String alias = "Fre";
}

Similarly other language classes.

And one more class called Language:

Class Language{
    String name = "";
    String alias = "";
}

Depending upon my requirements I want to cast English/French/Spanish to my Language class.

Class ABC{

    main(){
        Language lan = new Language();
        Object obj = getObject(1);
        if(obj instanceof English){
            lan.name = ((English)obj).name;
            lan.aliasName = ((English)obj).aliasName;
        }
    }

}

If I have 10 languages, do I need to write the same code for 10 different languages? In this case, how can I make a single method and pass those arguments as parameters? Something like this:

setVariablesForLanguage(String className, Object obj)

Here i showed only 2 variables but my class will contain more than 100 variables.. My actual rewquirment is I want to set the my Language variables From one of those languages..

+3  A: 

Use an interface or an abstract class which declares Name and Alias properties. Implement the interface or derive from the abstract class for each of your classes.

This is the general principle which works for the common problem of "lots of classes which look very similar" - but what's really going on here? Why would you have multiple instances of English? What's the real state here?

Do you actually want a sort of smart enum?

Jon Skeet
A: 

Why not make English, French, etc. all a subclass of Language?

Then your code would be simpler:


Class ABC{

main(){

 Language lan = getObject(1);

}

}

Edit: As stated above, Language may also do better as an interface or abstract class.

theycallmemorty
As used above, the behavior of the concept 'language' maps on to one class. Each language would be an instance of this class. Defining a subclass for each language would not (at all) help to avoid code duplication!
xtofl
+13  A: 

If you're making several small classes each holding constant values, you shouldn't be making them classes. I suggest making them constant instances of Language:

public static final Language ENGLISH = new Language("English", "Eng");
public static final Language FRENCH  = new Language("French",  "Fre");

And give Language a constructor to match. (Actually, this is looking more like an enum, but I won't dump too much on you at once.)

Then in your main code, don't check if it's an instance of English, French, etc. Simply check if it's a Language, then call

Language lan = new Language();
Object obj = getObject(1);
if(obj instanceof Language){
    lan.name = ((Language)obj).name;
    lan.aliasName = ((Language)obj).aliasName;
}
Michael Myers
+1, just what I wanted to post (maybe besides the isinstance-stuff, as I dislike such ;) )
Tetha
The principle here being 'Subclass to change behaviour, not data'. Since the behaviour doesn't change, you don't need more than one class.
Brian Laframboise
Actually you probably want enums, but the functionality would be pretty much the same as what this answer suggested.
Bill K
+2  A: 

If I have 10 languages, do I need to write the same code for 10 different languages?

No, actually probably you don't even need the classes at all.

If they have the same properties and the only thing that makes them different is the values of these properties, you could have a single class ( Language ) and use different values for each language.

BTW so you mean alias when you say alais?

You could have it like this:

public class Language  {

    String name;
    String alias;

    public Language( String aName, String anAlias ) { 
        this.name = aName;
        this.alias = anAlias;
    }
}

And set the values accordingly.

If you change the signature of "getObject()" so, instead it returns object, it return Language itself then you could change your code from this:

Language lan = new Language();

Object obj = getObject(1);

if(obj instanceof English){

    lan.name = ((English)obj).name;

    lan.aliasName = ((English)obj).alias;
}

To this:

Language lang  = getObject(1);

And that's it. Inside getObject you could define it like this:

public Language getObject( int id ) { 
     switch( id ) { 
          case 0:  return new Language("English", "ENG");
          case 1:  return new Language("French", "FRE");
          case 2:  return new Language("Spanish", "ESP");
          case 3:  return new Language("German", "GER");
          case 4:  return new Language("Portuguese", "POR");
          ....
          etc. 
      }
}

As you may realize, making a subclass or different classes make sense when the behavior is different. When the behavior is the same, and the only thing that changes is the data, then parameterizing the class will be enough.

Final remark:

Depending on your needs you could probably take a look at the Locale class and probably read this article to know what's does Java have for this kind of situations. I don't know if your code needs it or don't, bu it may be helpful.

OscarRyz
Why won't you just do return new Language( ((Language)obj).name , ((Language)obj).alias) just once. whats up with writing such switch case block and duplicating code 'n' times?
Chandan .
@Livepool: I don't even know what's inside the getObject method, most likely the object is created inside. Why would I create Object while we can create the very Language instance. Only "Chinni" can tell.
OscarRyz
+1  A: 

This is not a full solution for your question (it may not even be a real solution for you), but I wanted to point out some things that I think would be better with the code you provided.

For the code provided, you would be better off writing something like this:

abstract class Language
{
    private final String name;
    private final String alias;

    public Language(final String m, final String a)
    {
        name  = n;
        alias = a;
    }

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

    public String getAlias()
    {
        return (alias);
    }
}

class English
    extends Language
{
    public English()
    {
        super("English", "ENG");
    }
}

class ABC
{
    public static void main(final String[] argv)
    {
        fnal Language lang;

        lang = getObject(1);
    }
}

In general:

  • You should avoid instanceof as much as possible.
  • When you have things that are of the same type (like English, French, etc... you should make a parent class and put the common things in it).
TofuBeer
- When the only thing that changes is data, just parametrize, don't subclass.
OscarRyz
I agree - I was just fixing the code presented...
TofuBeer