Java if or separate classes

Separate files for class definition and declaration in Java

I’m a C++ programmer currently learning Java and I’m wondering if OOP in Java follows the same principle of separation of class definition and declaration as C++ does, ie. place them both in separate files. I’ve had a look around the internet, including the Android developer website, and all the code I’ve come across has the definition and declaration carried out at the same time. Is this simply one of the difference between development in C++ and development in Java, or are the sources I’ve been looking at simply doing things that way to limit the complexity of their code for posting on the internet? I have seen declarations and definitions combined in some C++ documentation, though I know it is bad practice to do so.

What’s with everyone and interfaces? That’s absolutely not what they are for. Separating a single class into interface and implementation makes no sense: they exist to allow a lightweight form of multiple inheritance, to describe a general behaviour that can be implemented separately. This is different from C++’s separation of definition of a specific class.

Separating a single class into interface and implementation makes perfect sense when the class is «heavy» and you want an easy way to, for example, create a mock for your testing code. Of course, doing it for very simple classes may be overkill.

Читайте также:  Java сортировка массива строк

Quite; the distinction between classes and interfaces in Java has very little in common with that between headers and definitions in C++.

7 Answers 7

There is a practical reason for separating declaration in C++, and it’s to allow source files to be compiled separately. There is no such need in Java (as everything is compiled to bytecode separately), so it isn’t allowed.

Another reason for the separation in C++, as I recall, is that you can give someone your class’ public interface without giving them the code. In Java, this metadata is in the .class file, so you don’t need a separate header.

@yshavit true, of course; it all comes down to being able to compile without having to include the other classes’ source (respectively for perfomance and for security reasons).

The below answer has been edited heavily based on the comments.

You do not need to split your class into definition and declaration purely for the compiler’s sake, as there is no need for forward declarations in Java (as there is in C++). You may want to split a class definition and declaration into an interface/class pair (or [abstract] class/class pair) due to design requirements, such as:

  • Multiple classes implementing a single interface.
  • Remote Procedure Calls, where you don’t want to expose any of your class dependencies (since they may not be available on the client side)
  • Class that is used by other classes, but you don’t need/want its full functionality when testing (ex. database access service which you may want to mock in your test code)

However, this is more akin to using a virtual base class and concrete implementing classes in C++ and is often called «programming to an interface». You can read more about the technique in this article (with some arguments there why you may prefer to use an abstract class instead of an interface as the base). Also, such splitting should be considered carefully; in many cases, splitting a class is just pure overkill and will lead to unnecessary code bloat.

Therefore, the short answer is: you don’t need to split the class only for the sake of having forward declaration (which the original question asks), though you may want to do it if there is a design reason to (but this is not the equivalent of C++’s header/class file split).

Источник

Calling different classes with an if statement in java?

I am programming an TBAP (Texted base adventure program) just because. I just started it, and I am already having issues with it. What I want to do is have a main class that introduces the program, in output text. At the end of the class it asks «Where would you like to go on your adventures?» It has five options 3 of them are separate adventures of two of them are inventory classes. Right now I am stuck on the my first adventure class. I have an int variable called path. If path == 1, you go to fantasy island class go on your adventure. Is there any to call that adventure with an if statement? I made a constructor and getters and setters with my variables name and path. Summerproject class:

package summerproject; import java.util.Scanner; import static summerproject.Fanastyisland.name; import static summerproject.Fanastyisland.path; public class Summerproject < private static int path; private static String name; public Summerproject (int path, String name) < this.path = path; this.name = name; >public String getname() < return name; >public void setname(String name) < this.name = name; >public int getPath() < return path; >public void setPath(int path) < this.path = path; >public static void main(String[] args) < Scanner in = new Scanner(System.in); System.out.println("Welcome to the adventure text program! You are the choosen one to save the universe"); System.out.println("Press any key to continue. "); try < System.in.read(); >catch(Exception e) <> System.out.println("Welcome. You are the choose one, a legend,a becon of hope to save the universe from the forces of evil."); System.out.println("Only with you skills and your great power can you destroy the evil doing world."); System.out.println("Please enter heros name"); name = in.next(); System.out.println("Okay " + name + ", lets begin our adventure!!"); System.out.println("The world can be saved, there is hope. But in order to save the world, \n " + "+ you must complete 9 tasks in three diffrent places in three diffrent periods of time. The past, the present and the future."); System.out.println("Press any key to continue. "); try < System.in.read(); >catch(Exception e) <> System.out.println("The three places are the past in the year 1322 in Fantasy island"); System.out.println("The present is the evil little town of Keene N.H."); System.out.println("And the future to the year 2567 in Space!"); System.out.println("Where would you like to go on your adventures?"); System.out.println(" 1). Fantasy Island"); System.out.println(" 2). Keene"); System.out.println(" 3). Outer space"); System.out.println(" 4). Buy wepons or potions!"); System.out.println(" 5). Sell wepons!"); path = in.nextInt(); if (path == 1) < >> > 
package summerproject; import java.util.Scanner; import static summerproject.Fanastyisland.name; import static summerproject.Fanastyisland.path; public class Fanastyisland extends Summerproject < public static String name; public static int path; public Fanastyisland (String name, int path) < super(path,name); name = name; path = path; >public String getName() < return name; >public void setName(String name) < this.name = name; >public int getPath() < return path; >public void setPath(int Path) < this.path = path; >public static void main(String[] args) //this is where the fantasy island adventure begins. < System.out.println("Welcome to fantasy island!!") >> 

Like I said, I want to call the sub classes with an if statement and I don’t know how to do that. If I type in one 1, I want to go to the fantasy island class. I haven’t programmed the adventure yet, I will get to it once it is fixed, I just want the output for now to be «Welcome to fantasy island!» when I type 1. Any help would be great! Thank you!

Источник

Multiple If-else or enum — which one is preferable and why? [closed]

Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.

public class FruitGrower < public void growAFruit(String type) < if ("wtrmln".equals(type)) < //do watermelon growing stuff >else if ("ppl".equals(type)) < //do apple growing stuff >else if ("pnppl".equals(type)) < //do pineapple growing stuff >else if ("rng".equals(type)) < //do orange growing stuff >else < // do other fruit growing stuff >> > 
public class FruitGrower < enum Fruits < WATERMELON < @Override void growAFruit() < //do watermelon growing stuff >>, APPLE < @Override void growAFruit() < //do apple growing stuff >>, PINEAPPLE < @Override void growAFruit() < //do pineapple growing stuff >>, ORANGE < @Override void growAFruit() < //do orange growing stuff >>, OTHER < @Override void growAFruit() < // do other fruit growing stuff >>; static void grow(String type) < if ("wtrmln".equals(type)) < WATERMELON.growAFruit(); >else if ("ppl".equals(type)) < APPLE.growAFruit(); >else if ("pnppl".equals(type)) < PINEAPPLE.growAFruit(); >else if ("rng".equals(type)) < ORANGE.growAFruit(); >else < OTHER.growAFruit(); >>; abstract void growAFruit(); > public void growAFruit(String type) < Fruits.grow(type); >> 

I see that enums code is longer and may be not as clear as if-else code, but I believe it’s better, could someone tell me, why I’m wrong (or maybe I’m not)? Are there any concerns about using enum instead of if-else?

Ignore the people who say that you should use polymorphism instead of enums. That’s like saying you should use a vehicle instead of a car. Java’s enums are objects and support polymorphism, which is the feature that you use. I’d prefer your if/else solution or your enum solutions before any of the other suggestions in this thread. Which one to use depends on the circumstances.

@Martin: I agree what to do depends on the circumstances, but do not agree that an object-oriented solution (what you label as «polymorphism») should be ignored. Also, contrary to what you suggest, the enum example does not use polymorphism — it still uses an if-else to select which Fruit to call. That kind of code is not extensible without modification. The OO version is.

@SingleShot: Yeah, you’re right, gasan’s code doesn’t use polymorphism. It just looks like it should. Other than that, my thinking was sound. 🙂

14 Answers 14

You’ve already got good answers about improving your use of Enums. As for why they’re better than string constants:

I think the biggest benefit is compile-time error checking. If I were to call growAFruit(«watermelon») , the compiler would have no idea anything was wrong. And since I’ve spelled it correctly, it’s not going to stand out as a mistake when you’re viewing the code. But if I were to WATERMELEN.growAFruit() , the compiler can tell you immediately that I’ve misspelled it.

You also get to define growAFruit as a bunch of simple, easy-to-read methods, instead of a big block of if — then — else s. This becomes even more apparent when you have a few dozen fruits, or when you start adding harvestAFruit() , packageAFruit() , sellAFruit() , etc. Without enums you’d be copying your big if-else block all over, and if you forgot to add a case it would fall through to the default case or do nothing, while with enums the compiler can tell you that the method hasn’t been implemented.

Even more compiler-checking goodness: If you also have a growVegetable method and the related string constants, there’s nothing stopping you from calling growVegetable(«pineapple») or growFruit(«peas») . If you’ve got a «tomato» constant, the only way to know if you consider it a fruit or a vegetable is to read the source code of the relevant methods. Once again, with enums the compiler can tell you right away if you’ve done something wrong.

Another benefit is that it groups related constants together and gives them a proper home. The alternative being a bunch of public static final fields thrown in some class that happens to use them, or stuck a interface of constants. The interface full of constants doesn’t even make sense because if that’s all you need defining the enum is much easier than writing out the interface. Also, in classes or interfaces there is the possibility to accidentally use the same value for more than one constant.

They’re also iterable. To get all the values of an enum you can just call Fruit.values() , whereas with constants you’d have to create and populate your own array. Or if just using literals as in your example, there is no authoritive list of valid values.

  • With an enum, you can use your IDE’s auto-completion feature and automated refactorings
  • You can use things like «Find References» in Eclipse with enum values, while you’d have to do a plain text search to find string literals, which will usually also return a lot of false-positives (event if you use static final constants, someone could have used the string literal somewhere)

The main reason not to use an enum would be if you don’t know all the possible values at compile time (i.e. you need to add more values while the program is running). In that case you might want to define them as a class heirarchy. Also, don’t throw a bunch of unrelated constants into an enum and call it a day. There should be some sort of common thread connecting the values. You can always make multiple enums if that’s more appropriate.

Источник

Оцените статью