How to fill a list with similar but different objects? - java

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"
}
}

Related

Invoking a static method over a list of "Class" objects [closed]

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.

How to access a Child class function in java [duplicate]

I have the following classes
class Person {
private String name;
void getName(){...}}
class Student extends Person{
String class;
void getClass(){...}
}
class Teacher extends Person{
String experience;
void getExperience(){...}
}
This is just a simplified version of my actual schema. Initially I don't know the type of person that needs to be created, so the function that handles the creation of these objects takes the general Person object as a parameter.
void calculate(Person p){...}
Now I want to access the methods of the child classes using this parent class object. I also need to access parent class methods from time to time so I CANNOT MAKE IT ABSTRACT.
I guess I simplified too much in the above example, so here goes , this is the actual structure.
class Question {
// private attributes
:
private QuestionOption option;
// getters and setters for private attributes
:
public QuestionOption getOption(){...}
}
class QuestionOption{
....
}
class ChoiceQuestionOption extends QuestionOption{
private boolean allowMultiple;
public boolean getMultiple(){...}
}
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption().getMultiple())
{...}
}
}
The if statement says "cannot find getMultiple for QuestionOption." OuestionOption has many more child classes that have different types of methods that are not common among the children (getMultiple is not common among the children)
NOTE: Though this is possible, it is not at all recommended as it kind of destroys the reason for inheritance. The best way would be to restructure your application design so that there are NO parent to child dependencies. A parent should not ever need to know its children or their capabilities.
However.. you should be able to do it like:
void calculate(Person p) {
((Student)p).method();
}
a safe way would be:
void calculate(Person p) {
if(p instanceof Student) ((Student)p).method();
}
A parent class should not have knowledge of child classes. You can implement a method calculate() and override it in every subclass:
class Person {
String name;
void getName(){...}
void calculate();
}
and then
class Student extends Person{
String class;
void getClass(){...}
#Override
void calculate() {
// do something with a Student
}
}
and
class Teacher extends Person{
String experience;
void getExperience(){...}
#Override
void calculate() {
// do something with a Teacher
}
}
By the way. Your statement about abstract classes is confusing. You can call methods defined in an abstract class, but of course only of instances of subclasses.
In your example you can make Person abstract and the use getName() on instanced of Student and Teacher.
Many of the answers here are suggesting implementing variant types using "Classical Object-Oriented Decomposition". That is, anything which might be needed on one of the variants has to be declared at the base of the hierarchy. I submit that this is a type-safe, but often very bad, approach. You either end up exposing all internal properties of all the different variants (most of which are "invalid" for each particular variant) or you end up cluttering the API of the hierarchy with tons of procedural methods (which means you have to recompile every time a new procedure is dreamed up).
I hesitate to do this, but here is a shameless plug for a blog post I wrote that outlines about 8 ways to do variant types in Java. They all suck, because Java sucks at variant types. So far the only JVM language that gets it right is Scala.
http://jazzjuice.blogspot.com/2010/10/6-things-i-hate-about-java-or-scala-is.html
The Scala creators actually wrote a paper about three of the eight ways. If I can track it down, I'll update this answer with a link.
UPDATE: found it here.
Why don't you just write an empty method in Person and override it in the children classes? And call it, when it needs to be:
void caluculate(Person p){
p.dotheCalculate();
}
This would mean you have to have the same method in both children classes, but i don't see why this would be a problem at all.
I had the same situation and I found a way around with a bit of engineering as follows - -
You have to have your method in parent class without any parameter and use - -
Class<? extends Person> cl = this.getClass(); // inside parent class
Now, with 'cl' you can access all child class fields with their name and initialized values by using - -
cl.getDeclaredFields(); cl.getField("myfield"); // and many more
In this situation your 'this' pointer will reference your child class object if you are calling parent method through your child class object.
Another thing you might need to use is Object obj = cl.newInstance();
Let me know if still you got stucked somewhere.
class Car extends Vehicle {
protected int numberOfSeats = 1;
public int getNumberOfSeats() {
return this.numberOfSeats;
}
public void printNumberOfSeats() {
// return this.numberOfSeats;
System.out.println(numberOfSeats);
}
}
//Parent class
class Vehicle {
protected String licensePlate = null;
public void setLicensePlate(String license) {
this.licensePlate = license;
System.out.println(licensePlate);
}
public static void main(String []args) {
Vehicle c = new Vehicle();
c.setLicensePlate("LASKF12341");
//Used downcasting to call the child method from the parent class.
//Downcasting = It’s the casting from a superclass to a subclass.
Vehicle d = new Car();
((Car) d).printNumberOfSeats();
}
}
One possible solution can be
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption() instanceof ChoiceQuestionOption)
{
ChoiceQuestionOption choiceQuestion = (ChoiceQuestionOption)q.getOption();
boolean result = choiceQuestion.getMultiple();
//do something with result......
}
}
}

method parameter vs. getter in subclass [closed]

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.

Is this polymorphism?

I recently was in an interview and during that interview I realized my programming concepts aren't as concrete as I thought.
I was asked, describe a time in your previous job where you used polymorphism?
After some thinking I said that we had a record class which every new record extended. So if we have a AddRecord or a RemoveRecord or any other type of record, they would extend Record. The record interface looked something like this:
public abstract Record{
public writeLine(String line);
public getColumn(int column);
public setHeader(String header);
...
}
public AddRecord extends Record{
public writeLine(String line){
// do something
}
// etc...
}
public MakeRecord{
Record r;
public setRecord(Object s){
if(s instanceof Record){
r = s;
}
}
public void printNewRecord(){
while(thingsToWrite){
r.writeLine(something);
}
}
}
I just shorthanded it so don't nit pick it please.
I told them this was using polymorphism because regardless of the record type, it could be wrote without knowing what type of record it was. This was valuable because we are writing files that needed to be padded correctly, either zero filled or padded with spaces etc...
If this isn't polymorphism, please tell me how I can change my example into something that uses polymorphism.
Long answer short: yes
Polymorphism is, according to webster:a (1) : existence of a species in several forms independent of the variations of sex (2) : existence of a gene in several allelic forms (3) : existence of a molecule (as an enzyme) in several forms in a single species b : the property of crystallizing in two or more forms with distinct structure
we are focused with definition a. this describes, in java terms, as using 1 "top" class to reference two "bottom" classes. That is shown in the above example, to the best of my knowledge.
A very basic example of polymorphism:
import java.util.ArrayList;
public class TestClass{
public static void main(String args[]) {
ArrayList animals = new ArrayList();
animals.add(new Bear());
animals.add(new Fish());
animals.add(new Animal());
for (Animal a : animals){
a.someMethod();
}
}
}
class Animal {
public void someMethod(){
System.out.println("I am an Animal");
}
}
class Bear extends Animal{
public void someMethod(){
System.out.println("I am a Bear");
}
}
class Fish extends Animal{
public void someMethod(){
System.out.println("I am a Fish");
}
}
The output of this is:
I am a Bear
I am a Fish
I am an Animal
So we can see here that the loop calling the methods on each type of object calls them all on Animal, and yet the actual method called on each object is that objects own implementation of that method.
Clearly for this to work every object in the collection MUST have an implementation of this method, although it can obviously use the superclass’ version if that is appropriate for that object.
This means that the objects in a collection (as an example of how it may be used) can be decided at runtime, and don’t have to be individually type cast back to their true form, but can simply be called by a parent class type or interface type. This allows for far more flexibility in the code, and makes it easier to maintain. It also allows for code which is more generic and loosely coupled.
So there it is in a nutshell. There are tons of examples online to have a look at. It’s a brilliant concept, and one which is well worth investing some time into understanding.
The example is not good for explaining polymorphism.
Addrecord is not good extension of Record class. Addrecord should be method and not a class.
So basically you should have Record class having Addrecord method and this method can be overriden by special records like - ColumnnameRecord.
In the case where you have specialRecord class derived from Record class and Record Class have methods which are overriden by derived classes then you have good examples of polymorphism.
Current example is technically correct but not conceptual correct.
Another example for Polymorphism:
abstract class PolyGeometricEntity
{
public int center_x__mm; // commen superset
public int center_y__mm; // commen superset
public void move(int d_x__mm, int d_y_mm) // commen superset
{
center_x__mm += d_x__mm;
center_y__mm += d_y_mm:
}
public abstract int area(); // commen superset on abstract level, but specialized at implementation level
public abstract void draw(); // commen superset on abstract level, but specialized at implementation level
}
class CircleEntity : PolyGeometricEntity
{
public override int area()
{
// circle specific
return 1;
}
public override void draw()
{
// draw a circle
}
}
class TriangleEntity : PolyGeometricEntity
{
public override int area()
{
// triangle specific
return 1;
}
public override void draw()
{
// draw a triangle
}
}
class PolyCanvas
{
List<PolyGeometricEntity> entities = new List<PolyGeometricEntity>();
void CreateEntity(string toCreateClass)
{
// assume that code is called by the ui
// you do not know what the user decides at runtime
// Polymorphism 'starting' now:
PolyGeometricEntity toCreate = null;
if (toCreateClass == "c") { toCreate = new CircleEntity(); }
else if (toCreateClass == "t") { toCreate = new TriangleEntity(); }
entities.Add(toCreate);
}
void ReDraw()
{
foreach (PolyGeometricEntity toDraw in entities)
{
toDraw.draw(); // polymorphism in action!
}
}
}

Define the methods of anonimous class created inside a method from the method caller

in a class i have
A a = new A(){
stuffhere
};
now i found that i need to create the new A inside a method and return it, but i have to define the stuffhere from the class caller. Is there a way in java to do so? Something like
A a = createAClass(){
stuffhere
};
public A createAClass()[T]{
return new A(){T};
}
or something similar. I would prefer not to use an interface to pass to the create method, since my anonymous classes not only override methods, but also adds attributes and new functions, and i don't think i can pass them with an interface..
Any thought?
EDIT for the -1ers (a simple comment would suffice)
with the syntax [T], obviously wrong, i meant something that can pass a generic code, let's say a copy-paste of code.
createAClass()[int a; String b; #override public void mymethod(){dosomethigb;} public void dosomethingelse(){dosomethingelse;}];
would work like
public A createAClass(){
return new A()
{
int a;
String b;
#override public void mymethod()
{dosomethigb;}
public void dosomethingelse()
{dosomethingelse;}};
};}
but if i write in another part of the program
createAClass()[float c; List d; public void yourmethod(){dosomething2;} #override public void dosomethingelse(){dosomethingelse2;}];
it would instead work like
public A createAClass(){
return new A()
{
float c;
List d;
public void yourmethod()
{dosomething2;}
#override public void dosomethingelse()
{dosomethingelse2;}
};}
My bad, i choose a bad may of making an example, but i thought it was the clearest way. Maybe i should have used X instead of T?..
Long story short:
i want create an anonymous class inside a method, but define what the anonymous class does in the method caller, and not inside the method(like the title says)
EDIT2:
i know i can't access the new methods from the class, what i do now is create an anonymous class, add a few attributes and method, and then use them in an overridden method. The added methods are not a problem, since i can make the method caller to pass an interface that is called by the overridden method in the anonymous class created, the problems are the attributes. I don't know how to add them in the anonymous class passing them from the method caller.
Something like the following usually works:
public A createAClass(final String value){
return new A(){
// some code here that can access value
};
}
If you are looking for something else, please clarify the question.
Edit
Answer is no you can't do that. You are trying to create an A with no defined API for A. Even if you could do what you propose, how would any user of A know what methods / fields are available if A is not defined somewhere? For A to be useful, you need to have an API that A implements.
Not sure whether fully understood by me. But the pattern is like this:
public class Here {
private int stuff;
public class A {
private A() { ... }
... ++stuff; ...
}
public A createA() { ... }
}
...
Here here = ...
A a = here.createA();
AFTER QUESTION EDITED:
The simplest way is to override a method:
final Object stuff = ...;
A a = new A() {
#Override
protected void onSomeEvent() {
... stuff.toString();
}
}
Then A can call onSomeEvent.

Categories