Call methods of childclasses only when child is casted into parent? - java

Suppose I have a class train, two child classes intercity and sprinter which are types of trains. Now say I want to print a list of trains. When it is an intercity it shoud print intercity and when it is a sprinter it shoud print sprinter.
I thought this would imply that I create a method print in intercity and in sprinter. However as the program is iterating throug a list with trains java insists on creating a print method in the class train aswell.
So how do I cope with this. I thought of creating the print method which checks whether it is an instance of intercity or sprinter, then casts it into the corresponding type and then calls the print method of that type.
However I want to become a better programmer and it does not look like the best solution to me.
So my question therefore is how should deal with the above described situation?

You create a print method in the Train super-class and override it in the sub-classes. This way you don't have to check the type of a Train object before printing it, and no casting is required.
public class Train {
public void print ()
{
// here you might have a default printing logic, or you could keep this
// method abstract and leave the implementation to the sub-classes
}
}
public class Sprinter extends Train {
#Override
public void print ()
{
}
}
public class InterCity extends Train {
#Override
public void print ()
{
}
}

Related

How to extract information from Java stack as individual data types and use in method call

I am trying to implement an undo feature by creating a stack of 2 subtypes.
I have a stack of parent type UserEntry holding two child types Assign and RelEntry.
Assign and RelEntry is both classes used to insert values (number and relationship) into a grid table.
There is a method call to insert the values into the table as their respective subtypes for example assignToTable() and RelEntryToTable().
I am trying to use a polymorphic method that can call both of these subtypes from the parent stack eg.
parentStack.assignAndRelEntryToTable();
When making the abstract class for UserEntry I have tried an addToPuzzle() method which I then implemented in both child classes however when trying to call using
for (UserEntry ue : stack){
puzzle.addToPuzzle(ue)
}
The method call requires a method specific to each sub-class. I've tried creating a method call for each subclass but the puzzle itself cannot be referenced from the sub-classes.
There are 4 classes working together here: UI, RelEntry, UserEntry, and Assign.
I am trying to create them for each loop within the UI class as this contains the puzzle variable.
If I understand your question correctly, you're looking for instanceof. It let's you check if an object is of given type. Using it you can determine subtype of the UserEntry, cast to desired subtype and call one of your methods accordingly. Something like so:
for (UserEntry ue : stack){
if(ue instanceof Assign){
Assign assign = (Assign) ue;
puzzle.assignToTable(assign );
} else if(ue instanceof RelEntry){
RelEntry relEntry = (RelEntry) ue;
puzzle.relEntryToTable(relEntry);
}
}
I have a hard time understanding your requirements exactly so I am going to be very generic.
Syntax might not be 100% correct but it should give the general idea.
public abstract class UserEntry{
abstract void somCommonMethod();
}
public class RelEntry extends UserEntry{
void someCommonMethod(){
//ownRelEntryLogic
}
}
public class Assign extends UserEntry{
void someCommonMethod(){
//ownAssignLogic
}
}
public Puzzle{
ArrayDeque<UserEntry> stack = new ArrayDeque<>();
public void undoLogic(){
stack.pop().someCommonMethod();
}
public void add(UserEntry anyInstanceOfUserEntry){
stack.push(anyInstanceOfUserEntry);
}
}
}
public class UI{
Puzzle p = new Puzzle();
p.add(new RelEntry());
p.add(new Assign());
}

One constructor with one argument that creates two different objects

So I'm taking a Java class, and one of the assignments we were given involves abstract data types (ADTs). In this assignment, we're supposed to implement an ADT known as Stack through a class called LinkedStack. LinkedStack has one constructor, but in the test cases my professor provided us, a new LinkedStack object can create either a new LinkedList object or a new ArrayList object. My issue with this is that no matter how I define my argument, I still get an error saying that the argument is incompatible with the classes.
I've tried a logical test to see whether the argument was called as a LinkedList or an ArrayList, which I think is a good thing, but I can't figure out how to properly assign the argument.
I've tried setting the argument to a Stack and then casting to a LinkedStack, with a private final variable being of of type "Stack", I've also tried calling the argument as a List, but I can't seem to get rid of the errors preventing me from starting the compiling process.
This is what we start out with:
interface Stack {
public void push(Object d){
}
public Object pop(){
}
public Object peek(){
}
public boolean isEmpty(){
}
}
public class ListStack implements Stack{
public ListStack(/*argument*/){
}
}
//Separate test case file
//example of the test cases
public void peekTest1() {
Stack q = new ListStack(new LinkedList());
// assertion cases follow
}
public void peekTest2() {
Stack q = new ListStack(new ArrayList());
// assertion cases follow
}
If you look for a type that you can use for /*argument*/, you can do it like this:
public class ListStack implements Stack {
public ListStack(List list) {
}
/* note that you must implement all methods from the interface */
}
Why use type List? List is the common interface, implemented by LinkedList and ArrayList. So you can use one of them in the constructor.
Note: You should not use raw types. List and the classes that implement this interface have a type parameter. When possible you should rather use something like List<String> or List<T>. But maybe, you will learn this in a later lesson.

what is dynamic method resolution

I am currently reading Herbert Schildt "Java the Complete Reference" and there he has used a term "Dynamic method resolution" and has provided a little explanation, but i am not getting the full import of it so asking for help in this forum.
while discussing 'interfaces', what he is saying is, dynamic method resolution helps in resolution of method name at run-time and it is achieved by declaring a interface variable and using it to refer to a class object. i.e
interface i = new object();
now what is so unique about it? you can use a class variable also to refer to the same object like:
class c = new object();
so, what is the use of interface here? and why introduce this new term "dynamic method resolution"??
Second he makes a point by saying: " when we use an interface variable to refer to instance of any class, and when you call a method through these interface variables, the method to be executed is looked up dynamically at run time allowing classes to be created later than the code which calls method on them. The calling code can dispatch through an interface without having to know anything about the callee".
Now, Anything dealing with objects has to be in run-time as objects are created at runtime, Now, I dont understand what he meant by "allowing classes to be created...on them".
Any help will be appreciated.
Here is a little example:
public interface Animal {
public String sound();
}
public class Cat implements Animal {
public String sound() { return "meow"; }
}
public class Dog implements Animal {
public String sound() { return "woof"; }
}
public class Test {
public static void main(String[] args) {
Animal a;
if (args.length > 0)
a = new Cat();
else {
a = new Dog();
}
System.out.println(a.sound()); // prints "MEOW" or "WOOF"
}
}
What is so unique about it? You can use a class variable also to refer to the same object
Yes. But you cannot use a single class variable to refer to an instance that can be an instance of any class that implements the interface.
In Test class, if I declared a to have type Dog or Cat there would be no way to get the code to compile. Without the ability to declare Animal a, I would need to have two distinct variables, and two separate print statements.
This is what dynamic method resolution (aka polymorphism) gives you.
To understand his second point:
public class Test2 {
public static void main(String[] args) {
Animal a = PetShop.buyPet(args);
System.out.println(a.sound()); // prints "MEOW" or "WOOF"
}
}
The Test2 class will work with my Cat and Dog class from above. It will also continue to work without recompilation if in 3 years time I implement a Goldfish class and modify my PetShop class to stock aquatic pets. And indeed, it is even possible to implement the PetShop class so that it doesn't need to be changed or recompiled to support other kinds of pets.
Now, these examples are clearly not practical. However, the Java features that they illustrate are useful in real Java applications. Indeed, a program as simple as a classic "hello world" program relies on dynamic method lookup.
dynamic method resolution means Single method which can be applied to solve multiple problems. Ex: Consider Shape is an interface and has method name draw.
you have Rectangle and Circle classes implements Shape Interface. So when you create instance of Rectangle object and call the draw method will draw the Rectangle shape.. In other case you can instantiate Circle instance and call draw method to draw Circle...
In interface you may assign child object in the parent container.
Ex: Shape p = new Rectangle();
in this case it will create the instance of Rectangle and assign it into Shape p..
but from the Shape p object you can call only the draw method... you can not call other methods in the Rectangle Object since its assigned to parent interface and parent has only draw method.

Java: most efficient way of changing method arguments

I have a problem. So, assume there is this class native to the JRE with 100+ methods:
class HundredMethods {
public void method1(int) {
}
public void method2(int) {
}
... (98 more methods)
}
and I want to alter the arguments of 5 of those methods. Specifically, integers to doubles. and add an extra double argumentMy current solution involves a wrapper class that:-A: Provides direct access to the original class
-B: Has five methods that "translate" double arguments (with some extra inputs) into the integer arguments of the original. So:
class WrapperMethods{
public HundredMethods original = (assigned at constructor)
public void method1(double,double(extra)) {
int i = (assigned a value in "code" below)
this.original.method1(i);
}
}
Is there another lightweight solution to both changing and adding arguments to a few methods in a "heavy" class besides the one above? In terms of actually implementing this solution in my code, I've found that it can get messy when a user doesn't know what methods the wrapper class changes. In fact, I have a roughly 250+ method class that I'm changing 25 methods of, so the bigger the class, the messier my code becomes. Considering that I want to publish my code as public, someone would have to look up what methods the wrapper changes every time they wanted to use the wrapper.
Thanks!
You can make a subclass and add in 2 methods for each of the five methods that you want to modify. One that takes a double, that does your logic and does a super. invocation to the original method, and one that takes an int and makes sure that it does the same thing as when you pass in a double.
All the other 95 methods will still be accessible through your subclass as normal.
class WrapperMethods extends HundredMethods {
public void method1(double d) {
int i = (assigned a value in "code" below)
super.method1(i);
}
public void method1(int i) {
// Make sure that any calls that happen to pass in an integer,
// also go by your logic.
this.method1((double)i);
}
}

Calling a specific member of an object array from another class-method

I am now working on the AI section of my project. I am calling a method from my AI class which is intended to calculate where the Gladiator objects I have drawn need to actually end up. I passed to that method a List containing all my objects I want to place. A previous method from the AI class has determined where they want to be from each other, distance-wise and I have stored it as gladiator[0..1..2..etc].movementGoal.
Although the project is not real time, ie I will want to just "step" through it in the end, I do want simultaneous movement to occur. This means that my standard method of iterating through the list will not work as I need information about the other Gladiator's movement decisions in order to figure out any one Gladiator's actual movement as these decisions interact.
How can I access another specific gladiator's variables when I am outside the class and only have them in List form?
Edit:
I guess I could iterate through and test for a variable gladiatorNumber to be correct, then when it is pull that info? That would be pretty round-about but its all I can think of.
Edit2:
As requested, some code. My method in Ai class looks like this:
public void moveAI(List<Gladiator> gladiators) {
My gladiator is defined as such:
public class Gladiator {
Gladiator class is created as an array then added into a list in a separate main class. I don't really want to include more code than this, as there is a ton of it. Basically it boils down to how can I call gladiator[0] from AI class even though I created said object in the main class and only have them in list form in the AI class. Assume all variables in Gladiator are public. The error I am getting is cannot find symbol referring to gladiator[0...1...2...etc].
I think your problem boils down to wanting to pass the arrays of gladiators to another class. That should be fairly easy. If you in your main-class have these two defintions (note you only need one, I recommend the list as it is more versatile, arrays have fixed-length).
You want something like this:
public class Main {
// ....stuff
// This is the main class that keeps the list of gladiators
private List<Gladiator> gladiatorsList;
private Gladiator[] gladiatorsArray;
private MovementAI movementAI;
public Main() {
// You initialize gladiatorsList and gladiatorsArray as before
// gladiatorsList = ...
// gladiatorsArrray = ...
// Now you want to pass this list/array to another class (the AI), you
// can do this in the constructor of that class like so:
movementAI = new MovementAI(gladiatorsList);
}
// ...stuff as before
}
The AI
public class MovementAI {
private List<Gladiator> gladiators;
// Giving the class the list-reference, this list will be the same as the
// list in main, when main-list changes so does this one, they point to the
// same list-object, so the reference is only needed once.
public MovementAI(List<Gladiator> gladiatorsList) {
this.gladiators = gladiatorsList;
}
// The class already has a reference to the list from its constructor so it
// doesn't need the list again as a parameter
public void moveAI() {
}
// If you don't want to keep a reference to the list in this class but only
// use it in a method (I would not recommend this)
public MovementAI() {
}
// You need to pass it gladiatorsList everytime you call this method.
public void moveAI(List<Gladiator> gladiators) {
}
}
I see in your last comment that you have decided to let the AI decide to repaint if it meets a criteria, that is not recommended, you should keep responsibilities separate in your classes, less error-prone and better development. It is recommended to let the AI change the list of gladiators (move them, kill them etc) and the rendererclass simply paint every gladiator.
It also seems you want to have every gladiator be able to hold another gladiator as a target, it is better for them to hold the target as an Object, this way you don't have to search the entire list to find out which gladiator the gladiatornumber refers to and you don't have to think about ordering in the list. Something like this:
public class Gladiator {
// ..other stuff
private Gladiator target;
public Gladiator getTarget() {
return target;
}
public void setTarget(Gladiator target) {
this.target = target;
}
}

Categories

Resources