This might (most certainly will) sound stupid, but I am stuck and I cant find a proper solution to my problem.
I have a superclass and two sub classes extend it. On the parent class based on a condition I want to call the method from either of the two classes. This is inside a loop, so instead of doing the same check I decided to do the check once, create an object from the super class and then change the object to either one of the two sub classes. i.e.
public class Parent{
public void method() {
Parent object=new Parent();
if(a==b) {
object=new Child_A();
}else {
object=new Child_B();
}
for() {
object.method();
}
}
public void method() {
//empty method. need it just to compile
}
}
public class Child_A extends Parent{
public void method() {
//do something useful
}
}
public class Child_A extends Parent{
public void method() {
//do something useful
}
}
I had to write the Parent.method(), cos otherwise the compile would complain that there is no method() method on class Parent.
So with this, the method called is not one of the children,but the parents method.
I have read that objects need to be assigned directly to the class, like Childen_A object=new Childen_A. The thing is that I would like to use the same command for both cases (object.method()) no matter which class it refers to. Strange thing is that during debug, i see that object is of type Child_A, nevertheless the super method is called.
I know that the solution would be to create two different objects, one for each sub class, but that would make my code a bit more ugly and i would have to use the if statement inside the loop.So the correct way of doing it must be
public void method() {
for() {
if(a=b) {
Child_A object=new Child_A();
object.method();
}else {
Child_B() object=new Child_B();
object.method();
}
}
}
Is there a way to avoid the if statement inside the loop? Thanks
Your code should be
public class Parent {
public void method() {
}
// OR
public abstract void method(); // and make the class abstract as well
}
public class Child_A extends Parent {
#Override
public void method() {
//do something useful
}
}
// same with Child_B
Related
The following is a popular use case involving abstract method and overridding.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
abstract class Parent {
abstract void method();
}
class Child_A extends Parent {
#override
void method() {
do the task for Child_A;
}
}
class Child_B extends Parent {
#override
void method() {
do the task for Child_B;
}
}
It seems that we can always achieve the same thing by defining a generic method in the superclass, which uses the instanceof keyword to determine the subclass and performs the corresponding task for the subclass.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
class Parent {
void method() {
if (this instanceof Child_A) {
do the task for Child_A;
}
else if (this instanceof Child_B) {
do the task for Child_B;
}
}
}
class Child_A extends Parent {
}
class Child_B extends Parent {
}
Which code style is better and why?
Because:
you don't want to have to modify the parent class every time you add another subclass
in some circumstances like a library API you may not even know all the subclasses
code that deals with a subclass should be in that subclass, not in the parent.
If you do the latter, your subclasses becomes useless. They don't do anything. I'd like to think of it this way, the parent passed you the ability to do methodA in your own way. However in your case, the parent does everything, meaning you are dependent on your parent forever. Who would want that?
Well aside from that, when you create a new subtype, you'll have to edit also the parent(very absurd), think of what will happen 100 subtypes later. Give your subtypes the power to have their own individuality.
I have some problems using this keyword. If I have a couple of classes implementing another class, how can I use their values without calling the class itself? I explain.
//this is my first class
public class Foo extends FooHelper{
public int fooInt;
public String fooString;
//getter/setter below
}
//this is my second class
public class Foo2 extends FooHelper{
public double fooDouble;
public float fooFloat;
}
//this is my main method, i'm using it for calling the value.
//I omit all the thrash code before.
//This is how i want to call the method:
//imagine before there are onCreate, activity,...
Foo foo = new Foo().GetFooInt();
//this is the class extended from the firsts
public class FooHelper{
public void GetFooInt(){
//here is my problem, i need to call the Foo class and the fooInt value.
//I want also to be able to edit the Foo object, for example:
if(((Foo)this).getFooInt() == 0){
(Foo) this.setFooInt(5);
}
}
}
This is what i want to achieve, acces a class which extends another class with the only this keyword from the extended class. How can I do it?
EDIT:
I badly explained i think.
My problem is that i want to access my Foo object inside the FooHelper, not FooHelper's method inside Foo object.
Example:
after using this code:
Foo foo = new Foo();
foo.HelperClassMethod();
I need (in HelperClass) to access Foo object which invoked it.
public HelperClass<Foo> {
public void HelperClassMethod(){
//HERE i need to use the "foo" object which invoked this method
}
}
I added the <Foo>, probably I was missing it, is this correct? and how can i use this foo object in the method from the helper class? thanks all
EDIT2: i totally failed on my question i thinkm lets ignore the above code and just check below:
I Have to access an object inside the extended class's method.
I have this class:
public class Foo extends FooToExtend{
public int fooInt;
}
the class which is extended is this:
public class FooToExtend{
public void MethodOne(){
//HERE i need to access the calling object
}
}
now, in my main activity, I want to do this:
Foo foo = new Foo();
foo.MethodOne();
My doubt is how i can access foo object i created in main inside my MethodOne.
I have to change my FooToExtend in
public class<Foo> FooToExtend{
...
}
but I don't still know how to access the foo object inside it.
I see 2 problems here, understanding this keyword, and extending clases
PROBLEMS WITH this KEYWORD
Imagine you have a class and you are executing some code: keyword this refers to the class itself, if you where the object this would be the equivalent to me. Check here and here longer explanations, examples and tutorials.
PROBLEMS WITH extend
Also you must extend from top (interfaces or abstract classes) to bottom (extended) classes and implement in bottom part:
//this is the PARENT (FIRST) class extended from the CHILDREN (SECOND)
public abstract class FooHelper{
public abstract void GetFooInt();
}
//this is the CHILD (SECOND!!!) class
public class Foo extends FooHelper{
public int fooInt;
public String fooString;
#Override
public void GetFooInt() {
// are you sure you getFooInt method can return a null???
if(this.getFooInt() == null){
this.setFooInt(5);
}
//getter/setter below
}
EDIT 1
Oh ok, this was useful. one more question, a way is to use abstract, as you said, but is there a way to do the same without implementing it all times? just for info, my objective is to use Foo.FooHelperMethod() and be able in "FooHelperMethod()" to access Foo class. I hope i explained it, i don't know how to do it.. if it's impossible i will use abstract as you suggested :)
Sure, this is inheritance, simply don't declare abstract the parent, and implement the methods AND the attributes there, all the children will have this methods and attributes by extending the parent class.
Lets see this example:
//this is the PARENT (FIRST) class extended from the CHILDREN (SECOND)
class FooHelper {
int theIntCommonValue;
public int getTheIntCommonValue() {
return theIntCommonValue;
}
public void setTheIntCommonValue(int theIntCommonValue) {
this.theIntCommonValue = theIntCommonValue;
}
}
// CHILDREN CLASS, look how calling this.getTheIntCommonValue() (the parent method)
// doesn't throw any error because is taking parent method implementation
class Foo extends FooHelper {
public void getFooInt() {
if (this.getTheIntCommonValue() == 0)
this.setTheIntCommonValue(5);
}
}
class Foo2 extends FooHelper {
public void getFooInt() {
if (this.getTheIntCommonValue() == 3)
this.setTheIntCommonValue(8);
}
}
EDIT2:
My doubt is how i can access foo object i created in main inside my MethodOne.
ANSWER:
Passing the object as a parameter. But then, you need static class, not an extended one, lets see an
EXAMPLE:
Foo.java
public class Foo {
public int fooInt;
}
FooHelper.java
public static class FooHelper {
public static void methodOne(Foo foo){
//HERE i need to access the calling object
// for example, this?
if (foo.fooInt == 2)
}
}
Now, how do you execute it?
Main.java
public static void main(String[] args) throws Exception {
Foo foo = new Foo();
FooHelper.methodOne(foo);
}
NOTES
conventions say, methods in java start in LOWECASE and class name starts in UPPERCASE.
you must put both classes in sepparated files in order to allow static public class
I'm not sure I completely understand. But it looks as though you want GetFooInt to perform something differently depending on the class that extended it. So I think the best here to check the instanceof.
public class FooHelper{
public void GetFooInt(){
if(this instanceof Foo)
{
((Foo) this).fooInt = 5;
}
}
}
By the situation you want to named one class "Helper" I assume you will use it as a helper-class.
public class Helper {
public static int screenHeight = 500;
}
public class AnyOtherClass {
testSomething() {
System.out.println(Helper.screenHeight);
Helper.screenHeight = 510;
System.out.println(Helper.screenHeight);
}
}
For some basic understanding: this is the keyword you use in a non-static context to access the variables and methods of the Object you're currently inside. Proper use of this example:
public class SomeClass {
private int someInt;
public void setSomeInt(int someInt) {
this.someInt = someInt;
}
}
In this example the this is necessary because the local variable (/parameter) someInt has the same name as the global class variable someInt. With this you access the class varaible of the Object you're "in".
Example of unnecessary use of this:
public class SomeClass {
private int someInt;
public int squareSomeInt() {
return this.someInt * this.someInt;
}
}
Here you don't need the keyword this since there is no local variable called someInt.
On the other hand super is a keyword which accesses the variables and methods of the parent class (the class, your class is derrived from). Example:
public class SomeClass {
private int someInt;
public int squareSomeInt() {
return someInt * someInt;
}
}
the derrived class:
public class Other extends SomeClass {
public int squarePlusSquare() {
return super.squareSomeInt() + super.squareSomeInt();
}
}
i currently have a problem with generics. i want to transfer existing java code into c#. can anybody tell me, how i can do following in c# ?
For example i have a class named module with a generic parameter which inherits from basicdata. i want to add many of this objects to a handler so that they all can be updated in a single method.
in java i have something like this:
public class BasicData
{
}
public abstract class Modul<T extends BasicData>
{
T value;
abstract void update(); // do something with the value
}
public class Handler
{
LinkedList<Modul<?>> modulCollection = new LinkedList<Data<?>>();
void add(Modul<?> m)
{
this.dataCollection.add(m);
}
void update(){
for(Modul<?> d : this.modulCollection){
d.update();
}
}
}
the list should contain various modul-objects, where the value field itself can have various types but they all inherit BasicData.
i searched a while, but i only found exotic solutions. is there no easy way to do the similar thing in c#? i dont want to rewrite my whole design.
at first i thought i could declare the list like this in c#:
LinkedList<Modul<BasicData>> collection;
void add(Modul<BasicData> m)
{
this.dataCollection.add(m);
}
and then add the various objects like this:
class DataImpl : Modul<int>
{
}
handler.add(new DataImpl());
but i found out that you cannot cast this Modul.
is there a solution to do something like that?
thanks in advance,
mick
C# does not have the ? wildcard mechanics as Java has - What is the equivalent of Java wildcards in C# generics, so there is no direct native solution for this problem.
POSSIBLE SOLUTIONS:
1. Use base non-generic class or interface for your Modul:
public abstract class ModulBase : BasicData
{
abstract void update(); // do something with the value
}
public abstract class Modul<T> : ModulBase ...
or
public interface IUpdateable
{
void Update();
}
public abstract class Modul<T> : BasicData, IUpdateable...
And use it like:
public class Handler
{
LinkedList<IUpdateable> modulCollection = new LinkedList<IUpdateable>();
void add<T>(Modul<T> m) // It is generic now
{
this.dataCollection.add(m);
}
void update(){
foreach (IUpdateable d in this.modulCollection){
d.update();
}
}
}
Your Handler.moduelCollection is no longer generic with such an approach, but in any case(even in Java) you would not have been able to access different generics in a simple manner without casting - and that is not the best way to handle different datatypes put into one collection.
You could try the same in C# like below:
public abstract class Module<T> where T : BasicData
{
}
I think I got a solution for you. It kinda uses what others and you said and combines it with something not mention here.
If you have class Foo
class Foo {
public virtual void Method1() {
//Do something
}
public void Method2() {
//Do something
}
//class code
}
Now, you have a class Bar which inherits from Foo
class Bar : Foo {
public override void Method1() {
//Do something
}
public new void Method2() {
//Do something
}
//class code
}
If you declare a variable of the class Bar and try to convert it to Foo, it is completely acceptable and you don't loose any data. However, the next time you want to use the extra properties, methods and variables, you will need to convert it back to Bar. Though, if common members are an override, they should behave as if they were called by a Bar variable, otherwise, if the object is cloned or cast backwards, the common members should behave as if they were called by an Foo instance.
For example:
Bar myBar = new Bar();
Foo myFoo = myBar; //Now myFoo and myBar refer to the same memory address
Foo myFoo2 = myBar.Clone() as Foo; //myFoo2 and myBar do not refer to the same memory address
//These should do exactly the same thing because Method1 is an override
myBar.Method1();
myFoo.Method1();
//These should not do exactly the same thing unless Method2 was not changed in Bar
myBar.Method2();
myFoo.Method2();
//These should do exactly the same thing because Method1 is an override
myBar.Method1();
myFoo2.Method1();
//These should not do exactly the same thing unless Method2 was not changed in Bar
myBar.Method2();
myFoo2.Method2();
Bar myBarConvertedBack = (Bar)myFoo; //No data lost
Now back to the question. Try this:
public abstract class Module<T> where T : BasicData {
protected T value;
public abstract void Update();
public virtual T Value {
get;
set;
}
}
public class Handler
{
LinkedList<Modul<BasicData>> modulCollection = new LinkedList<Data<BasicData>>();
pulic void Add(Modul<BasicData> m)
{
this.modulCollection.add(m);
}
public void Update() {
foreach (Modul<BasicData> d in this.modulCollection)
d.update();
}
}
Consider this class as possible derived class from Module:
public class Class1: Module<BasicData> {
public Class1(BasicData val) {
base.value = val;
}
public override void Update() {
//Do something here
}
public override BasicData Value {
get {
return base.value;
}
set {
base.value = value;
}
}
}
Also see more cases in stackoverflow in the Related or Linked to this question if it is clear. Furthermore, if I'm wrong somewhere correct me
So, I want to be able to get an instance of a subclass that is being run when it calls a method from the super class. For example, if I had this class:
public class A {
public void aMethod() {
//Here is where I want to see if class B is calling the code
}
}
public class B extends A {
}
public class C {
B b = new B();
b.aMethod();
}
And, like the comment says, I want to check, in aMethod, if class B, the subclass of class A, is calling the code.
As has been pointed out to you, there is almost never a good reason to do this and I agree that you should be using polymorphism instead. However, if you "need" to do this or just want to know how to go about doing something like this, you can use instanceof on this inside of the method:
class A {
public void aMethod() {
if (this instanceof B) {
System.out.println("I'm a B!");
}
}
}
public class B extends A {
public static void main(String[] args) {
B b = new B();
b.aMethod();
}
}
public class A {
public void aMethod() {
if(this.getClass() == B.class){
System.out.println("huhuhuuuuuuuuuuuuuuuuu");
}
}
}
public class B extends A {
}
public class C {
public static void main(String[] args) {
B b = new B();
b.aMethod();
}
}
Check here: How to get the caller class in Java
The 2nd part of the answer from #dystroy is probably a start.
Note that this finds a call at any depth:
for(final StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getClassName().equals(B.class.getName())) {
System.out.println("BINGO");
}
}
If you want to check only a limited depth, don't iterate through all of the array.
This can be useful e.g. if some framework forces you to have a special method or a no-arg constructor to be present, but you don't want any developer to call this method directly. (Yes, it is a hack, but sometimes odd frameworks force you to do odd things). Then you can have an assertion in the unwanted method that just throws an exception if it is called by the wrong corner of your code.
Anyway you should try do avoid things like this if possible.
I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}