Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
We had a discussion in the office, but neither side was convinced. Lets say we have
enum Food {
CHICKEN, HAMBURGER, FISH;
}
We need multiple implementations of Dog, which need to answer, whether they are happy, which depends on whether they like food given to them and maybe some other stuff. It needs to be very flexible. Which is better:
A:
abstract class Dog {
//not sure if this can be abstract in reality, but does it matter?
abstract Set<Food> getFavoriteFoods();
boolean isFoodOk(){
return getFavoriteFoods().contains(Food.CHICKEN);
}
//in reality sometimes more conditions are needed here...
boolean isHappy(){
return isFoodOk();
}
}
public class BullDog extends Dog {
static final Set<Food> FAVORITE_FOODS = new HashSet<Food>();
static {
FAVORITE_FOODS.add(Food.CHICKEN);
FAVORITE_FOODS.add(Food.FISH);
}
Set<Food> getFavoriteFoods(){
return FAVORITE_FOODS;
}
}
OR B:
abstract class Dog {
abstract boolean isHappy();
boolean isFoodOk(Set<Food> f){
return f.contains(Food.CHICKEN);
}
}
public class BullDog extends Dog {
static final Set<Food> FAVORITE_FOODS = new HashSet<Food>();
static {
FAVORITE_FOODS.add(Food.CHICKEN);
FAVORITE_FOODS.add(Food.FISH);
}
#Override
boolean isHappy() {
return isFoodOk(FAVORITE_FOODS);
}
}
If the answer will be A I will have another question.
NOTE: I edited the code because there was a silly mistake there - of course FAVORITE_FOODS should be declared in BullDog, not Dog. But that does not answer the question.
I would say none, since in all the approaches the Set<Food> is marked as static final thus the same set will be shared among all the instances of Dog class. Also, by declaring the Set as static final doesn't mean its contents cannot be modified, so in fact any client of Dog class or any subclass may add new Food or even clear it and all the Dogs will be affected.
This approach could do:
public abstract class Dog {
//this field should be final only so the variable cannot be modified
protected final Set<Food> favoriteFood;
protected Dog(Food ... food) {
//now the Set cannot be modified as well
favoriteFood = Collections.unmodifiableSet(new HashSet<Food>(Arrays.asList(food)));
}
//no need to be abstract, and clients cannot modify this set
public Set<Food> getFavoriteFoods() {
//I would recommend returning a new set that
return favoriteFood;
}
//You need to check if the dog likes the food to see if its ok
public boolean isFoodOk(Food food){
//not sure if your requirement is that it always should compare with CHICKEN, really odd...
return getFavoriteFoods().contains(food); //Food.CHICKEN);
}
//IMO this method needs a complete redesign, since I don't know the details I can't provide a solution =\
//at most it can be an abstract method and let each dog subclass implement it
public abstract boolean isHappy();
//boolean isHappy(){
// return isFoodOk();
//}
}
public class BullDog extends Dog {
public BullDog() {
super(Food.CHICKEN, Food.FISH);
}
#Override
public boolean isHappy() {
//define how the bulldog is happy
return ...;
}
}
You'll get a very realistic model of the world: all dogs will be happy, no matter what food is available.
Seriously: neither A nor B are good, because the FAVORITE_FOOD is a class attribute of the abstract Dog class. It would make some sense to have it as class attribute per race. Or, more realistic, as instance attribute for each individual dog.
What is specific for Dog types is favourite foods. So they need to answer the question 'what is your favourite food?' with the implementation of getFavoriteFoods. Being happy is not a question to ask to all Dog types differently. So A is better, in my opinion.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
my question is more a personnal mind challenge than a production purpose... which means that despite there are obviously better ways to achieve my goal* , I am curious about how - AND IF - I could do it this way.
*I am thus not interested in other ways atm.
I would like to "register" within a list several classes objects (Foo.class, Bar.class, etc.) sharing a common static method inherited from a common parent class.
Then I want to iterate over this list, and invoke that static method.
The following code is wrong indeed, but it may at least show what I am trying to achieve:
======== Classes definition
public class SomeGenericClass {
public abstract static String getType();
}
public class SomeSpecializedClassA extends SomeGenericClass{
public static String getType(){
return "I am of type A";
}
}
public class SomeSpecializedClassB extends SomeGenericClass{
public static String getType(){
return "I am of type B";
}
}
======== Main
class Main{
void main(){
List<Class<SomeGenericClass>> classes = new ArrayList<Class<SomeGenericClass>> ();
classes.add(SomeSpecializedClassA.class);
classes.add(SomeSpecializedClassB.class);
for((SomeGenericClass.class)Class c : classes){
System.out.println(c.getMethod("getType", null).invoke(null, null));
}
}
}
========
Any idea?
sharing a common static method inherited from a common parent class.
This is impossible; static methods do not 'do' inheritance, hence why they are called static methods. There is NO way to specify that a given class adheres to a spec, where 'the spec' involves 'has static method XYZ'.
Why do you think java has the cliché of having 'factories'? A factory is just a container concept where a single instance of a class is the place you ask questions about the concept of another class: A "PersonFactory" is a class for which usually only a single instance exists and it answers questions about persons in general. Most usually the constructor (which doesn't 'do' specs/interfaces either), but anything else goes too.
Then I want to iterate over this list, and invoke that static method.
Reflection can do this. It'd be horrible code style, hard to maintain, and all around entirely the wrong way to go about it. You're asking me: "May I have a gun because there is an annoying mosquito balanced on my left toe", and that's the bazooka. If you want to take it and let er rip, okay. Your funeral.
So what's the better way?
Why is 'static' important here? It's not. Register 'TypeOracle' objects:
public interface CommandHandlerFactory {
String getCommand();
CommandHandler makeHandler();
}
public interface CommandHandler {
void handleCommand(UserInfo sendingUser, String cmdData);
}
public class WelcomeHandler {
#Override
public void handleCommand(UserInfo sendingUser, String cmdData) {
sendMsg("Well hello there, " + sendingUser.getUserName() + "!");
}
}
channelBot.registerHandler(new CommandHandlerFactory() {
#Override
public String getCommand() {
return "/hello";
}
#Override
public CommandHandler makeHandler() {
return new WelcomeHandler();
}
}
That's how you do it in a non-blow-your-feet-right-off fashion.
NB: A comment on your question suggest using asm. This is an utterly nonsensical comment; ASM has nothing to do with this and can't help you. Ignore this comment.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Hi friends!
I'm trying to do my homework. Now I am busy with the Cone.java part.
(F) balls >>> Flavor[]
How can I define that?
Well to break it down a bit for you.
Cone is a class that implements Eatable.
It has a field called balls. This is an array of type Flavors.
It also has two constructors. A basic constructor that has no arguments and a constructor that takes an array of type Flavors.
Finally it has a method called eat. This comes from the interface Eatable.
This would look a little like the following.
Eatable.java
public interface Eatable {
void eat();
}
Cone.java
public class Cone implements Eatable {
//The types of flavors
public enum Flavors {
STRAWBERRY,
BANANA,
CHOCOLATE,
VANILLA,
LEMON,
STRACIATELLA,
MOKKA,
PISTACHE
}
//The field
private Flavors[] balls;
//The constructors
//Constructor Basic
public Cone() {
balls = new Flavors[0];
}
//Constructor with Flavors
public Cone(Flavors[] balls) {
this.balls = balls;
}
//The methods
//You should always use getters and setters
//https://stackoverflow.com/questions/1568091/why-use-getters-and-setters-accessors
//Getter
public Flavors[] getBalls() {
return balls;
}
//Setter
public void setBalls(Flavors[] balls) {
this.balls = balls;
}
//Your method from UML
#Override
public void eat() {
//Whatever
}
}
This is simply a Dependency relation. You need to draw a dashed arrow from Cone to Flavor. This is because Flavor is an enumeration (the Mickeysoft or Eclipse notation you're using is wrong by the way, but you probably can't alter that except by staying away from the tool itself). The enumeration is used for balls to form an array of Flavors.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I was working on this question and I was wondering I have got it right.
Consider the interface MusicInterface which has a constant data member, TYPE,
which is equal to ‘Nice Music’ and a method play() which displays the TYPE on
console. The class StringedInstrument implements the interface
MusicInstrument.
i) Write the Java code for the interface MusicInstrument.
ii) Implement the abstract class StringedInstrument having variables
numberOfStrings of type integer and name of type String. No
implementation of method play is possible at this point.
iii) Implement the concrete class ElectricGuitar which is a subclass of
StringedInstrument having a constructor that initializes the name and
numberOfStrings and appropriate methods.
MusicInstrument class
public interface MusicInterface {
final String TYPE= "Nice Music";
public void play();
}
StringedInstrument class
public abstract class StringedInstrument implements MusicInterface {
public int numberOfStrings;
public String name;
}
ElectricGuitar class
public class ElectricGuitar extends StringedInstrument{
public ElectricGuitar(int numberOfString, String name){
super();
}
#Override
public void play() {
System.out.println("The type of music is: "+TYPE);
}
}
The question seems to be pretty straightforward so I was wondering if I made any mistake in understanding it.
Some notes for writing conventional Java code:
Change the visibility of the declared fields in your Abstract class StringedInstrument to be at least protected (or package-private). These fields are part of the state of the class and should be properly encapsulated.
Also, your ElectricGuitar constructor is kinda useless. It receives 2 parameters that are never used and the StringedInstrument's respective fields remain uninitialized. You should create a matching constructor in StringedInstrument and initialize the numberOfStrings and name fields in it, something like:
public StringedInstrument(int numberOfString, String name){
this.numberOfStrings = numberOfStrings;
this.name = name;
}
and ElectricGuitar would use this super constructor:
public ElectricGuitar(int numberOfStrings, String name){
super(numberOfStrings, name);
}
There is no particular reason for the class StringedInstrument to be abstract if it does not include any polymorphic abstract methods. I don't think this context would satisfy an appropriate example of abstract inherency.
That being said, whether you make it abstract or not, you should include in StringedInstrument:
public StringedInstrument(int numberOfStrings, String name) {
this.numberOfStrings = numberOfStrings;
this.name = name;
}
and in Electric guitar:
public ElectricGuitar(int numberOfStrings, String name) {
super(numberOfStrings, name);
}
I suppose if you put the TYPE in StringedInstrument you could do:
public abstract String getType();
and then in your specific class (ElectricGuitar) customize what getType() produces which is also a pretty weak use of an interface.
public abstract class StringedInstrument implements MusicInterface {
public int numberOfStrings;
public String name;
public StringedInstrument()
{
// This gets called by ElectricGuitar() constructor
}
#Override
public void play()
{
// I meant, you can also HAVE AN IMPLEMENTATION HERE. My Corrections
// OMITTING THIS METHOD BODY DECLARATION, WON'T CAUSE COMPILE ERRORS
// THAT WAS A BAD JOKE BY ME
System.out.println("The type of music is: "+TYPE + " In " + this.getClass().getSimpleName() );
}
}
Your Code stands solid
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
When it comes to Java programming you'll stumble upon this along your way. Here is an elementary answer to help new programmer learn how to use a getter method without the terminology or complexity of people is this field.
By creating an accessor method (and not creating a mutator method).
public class MyClass {
public MyClass(int v) {
this.myField = v;
}
private int myField;
public int getMyField() {
return myField;
}
}
Then you can call that "getter" in some other class with an instance of MyClass.
public class SomeOtherClass {
public static void doSomething(MyClass my) {
System.out.println(my.getMyField());
}
public static void main(String[] args) {
doSomething(new MyClass(42)); // <-- for example.
}
}
When working with Java projects you'll stubble upon "getter" methods or "get" methods. This is how I solved my problems, by following these instructions.
If you're confused on why you should use "getter" methods follow this link.
Note that this is for beginners and the language/format I use
may (and in some cases is) not be proper.
Note that you will also need to have a general concept of Java.
This is for people who don't understand some of the Java terminology
Take a look at my (example) project set up.
Package Explorer/Setup
Project Name
src
(default package/package name)
Class1.java
Class2.java
Class 1
public class Class1 {
// creates an object
static Class2 class2 = new Class2();
public static void main(String[] args) {
// this will print our method (method1) in our class (Class2)
System.out.println(class2.method1());
}
}
Class 2
public class Class2 {
// this is the method we are accessing
public double method1(){
// this is what we are returning (sending back)
return 2.5;
}
}
Output (console)
2.5
So how do we access a "getter" method?
If you haven't noticed already, we printed it in our class "Class1" using...
System.out.println(class2.method1());
we used class2. because we created an object that allows us to access our Class2. Notice that class2 is lowercase and Class2 is uppercase, this is because class2 (lowercase) is the object we've created. Thus we are using the object to use our "getter" method not our class. We create our object using...
static Class2 class2 = new Class2();
I have two classes lets say "QuestionOne" and "QuestionsTwo" which are very similar and inherit from a Baseclass "Question". Now I want to write a method which fills a ArrayList with Objects of either class.
public ArrayList<QuestionOne> list = new ArrayList<QuestionOne>();
public void fill(QuestionOne questionOne){
list.add(questionOne);
}
That would be a method to fill QuestionOne objects. But I want the method to be able to fill the list with both type of objects "QuestionOne" and "QuestionTwo".
What I would like to add...I want to use alle methods of "questionOne" and "questionTwo".
How can I achieve this? Do I need an Interface? I don't know...
Make an ArrayList<Question> and fill it up that way. Although you'll only have the interface available, that the Question class exposes.
If you use an abstract class Question, you will be able to use an arraylist of Question to store both subclass objects.
class Question{}
class QuestionOne extends Question{}
class QuestionTwo extends Question{}
ArrayList<Question> list = new ArrayList<Question>();
// This method will take any subclass of Question.
public void fill(Question question){
list.add(question);
}
To backcast, you can use instanceof to compare:
{ //...
for(final Question element:list){
if(element instanceof QuestionOne){
QuestionOne question=(QuestionOne)element;
// Use it here.
}
//...
}
}
public ArrayList<Question> list = new ArrayList<Question>();
Now list.add(x) will work whenever x is a Question or any object of a subclass of Question.
In general, any time you say that a variable or parameter has type C, it can contain a reference to a C or any subclass of C. This applies just as well to the parameter of the ArrayList add routine, which will look like this:
boolean add(Question e)
So you can add anything that is a subclass of Question to your list.
P.S.: Some comments are suggesting changing the parameter of fill also. You can do that, but you don't have to. It depends on your requirements. This will still work:
public void fill(QuestionOne questionOne){
list.add(questionOne);
}
since questionOne is a Question (as well as being a QuestionOne). If you really need to, you could overload fill:
public void fill(QuestionOne questionOne){
System.out.println("I'm adding a Type I question");
list.add(questionOne);
}
public void fill(QuestionTwo questionTwo){
if (questionTwo.isInteresting()) {
// assume isInteresting is a method that is defined only for QuestionTwo
System.out.println("I'm adding a Type II question");
list.add(questionTwo);
}
}
Usually it would be better to do something like this by adding a polymorphic method to Question that is overridden in QuestionOne and QuestionTwo. But this isn't always possible. I'm just bringing this up to point out that the parameter of fill doesn't actually need to change, although you might want to.
As mentioned, you can create an ArrayList of type Question. This means that you will only be able to use methods that are defined in the Question class.
For example
public class Question {
public void askAQuestion(){
System.out.println("Im asking a question");
}
}
_
public class QuestionOne extends Question {
#Override
public void askAQuestion(){
// You can override a method. As long as it has the same name and
// return type, it can have it's own functionality
System.out.println("Im asking question one");
}
public void doSomethingElse(){
// Because this method is not in the Question class, you cannot use
// it in your ArrayList
}
}
_
public class QuestionTwo {
#Override
public void askAQuestion(){
System.out.println("Im asking question two");
}
}
_
public class MainClass {
public static void main (String[] args){
List<Question> questions = new ArrayList<Question>();
questions.add(new QuestionOne());
questions.add(new QuestionTwo());
questions.get(0).askAQuestion(); // Outputs "Im asking question one"
questions.get(1).askAQuestion(); // Outputs "Im asking question two"
}
}