Results 1 to 11 of 11
  1. #1
    Gelembjuk is offline Member
    Join Date
    Oct 2008
    Posts
    9
    Rep Power
    0

    Default Returned type changes if class is extended. How?

    Hello.

    I want to do following program. Please let me know if this is possible in java.
    I have class that have one method that returns object of this class
    Java Code:
    public class MyTest1 {
        public MyTest1(){
            
        }
        public MyTest1 getCorrected(){
            MyTest1 a=new MyTest1();
            ......
            ......        
            return a;
        }
    }
    And i have another class that extends first one.
    Java Code:
    public class MyTest2 extends MyTest1{
        public MyTest2(){
            
        }
    }
    I want to execute this code. I think there is error (i didn't try it) because this method rertuns object of type MyTest1 not MyTest2. Even if there is no exception raised it is not good for me. Becouse method getCorrected works with all class properties and MyTest2 class can have more properties.
    Java Code:
    MyTest2 a=new MyTest2();
    ......
    MyTest2 b=a.getCorrected(); 
    //there is error
    Is it possible somehow to change type that methods returns depending if class is extended ?
    To make getCorrected() returns object of type MyTest2 if MyTest1 extended with MyTest2?

  2. #2
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    9

    Default

    Java Code:
    public class InheritTest {
        public static void main(String[] args) {
            A a = new A();
            System.out.println("a = " + a);
            System.out.println("a.getInstance = " + a.getInstance());
            B b = new B();
            System.out.println("b = " + b);
            System.out.println("b.getInstance = " + b.getInstance());
        }
    }
    
    class A {
        public A getInstance() {
            return new A();
        }
    
        public String toString() {
            return getClass().getName();
        }
    }
    
    class B extends A {
        public B getInstance() {
            return new B();
        }
    }

  3. #3
    Gelembjuk is offline Member
    Join Date
    Oct 2008
    Posts
    9
    Rep Power
    0

    Default

    Quote Originally Posted by hardwired View Post
    Java Code:
    public class InheritTest {
        public static void main(String[] args) {
            A a = new A();
            System.out.println("a = " + a);
            System.out.println("a.getInstance = " + a.getInstance());
            B b = new B();
            System.out.println("b = " + b);
            System.out.println("b.getInstance = " + b.getInstance());
        }
    }
    
    class A {
        public A getInstance() {
            return new A();
        }
    
        public String toString() {
            return getClass().getName();
        }
    }
    
    class B extends A {
        public B getInstance() {
            return new B();
        }
    }
    Yes. I know this. But i don't want to write that code each time. There will be a lot of classes that will extend root class (in example MyTest1) .
    So i need another way to do this.

  4. #4
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    9

    Default

    Java Code:
    public class InheritTest {
        public static void main(String[] args) {
            A a = new A();
            System.out.println("a = " + a);
            System.out.println("a.getInstance = " + a.getInstance());
            B b = new B();
            System.out.println("b = " + b);
            System.out.println("b.getInstance = " + b.getInstance());
        }
    }
    
    class A {
        public A getInstance() {
            return this;
        }
    
        public String toString() {
            return getClass().getName();
        }
    }
    
    class B extends A {
    }

  5. #5
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,327
    Rep Power
    25

    Default

    Is it possible somehow to change type that methods returns depending if class is extended ?
    To make getCorrected() returns object of type MyTest2 if MyTest1 extended with MyTest2?
    If MyTest2 doesn't override the getCorrected() method then the only one available is the one in MyTest1 which returns a MyTest1 object. When you extend a class, YOU must code the differences you want in the new class. In this case you want to change what a method returns. The problem if you do that is that the compiler complains about "differ in return type only"
    One solution is to cast the return value to what you KNOW it is. This requires you to write the method in every class.
    But i don't want to write that code each time
    Each new class will have to have a method that returns what is unique to that class.

    hardwired's code returns a reference to the extended class, but you want to get a new instance of that class.
    Last edited by Norm; 10-30-2008 at 11:13 PM.

  6. #6
    georgemc is offline Senior Member
    Join Date
    Sep 2008
    Posts
    135
    Rep Power
    0

    Default

    I have to ask why you want this, though. It doesn't seem a very nice design. Why are those subclasses subclasses? Do you have a concrete example of what you're trying to do?

  7. #7
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,327
    Rep Power
    25

    Default

    Your idea will work if you change what getInstance() returns in hardwired's code to:
    return (A)this.clone();
    This will require a few other minor coding changes.

  8. #8
    Gelembjuk is offline Member
    Join Date
    Oct 2008
    Posts
    9
    Rep Power
    0

    Default

    Quote Originally Posted by georgemc View Post
    I have to ask why you want this, though. It doesn't seem a very nice design. Why are those subclasses subclasses? Do you have a concrete example of what you're trying to do?
    Ok. i will describe what i want to do.
    I am new in java and maybe there is more simple way to do this.

    As i said i code root class that will be extended with a lot of classes and subclasses. This root class must have some methods that will be in all classes and i don't want to back to this methods when coding subclasses. And there will be another programmers so i don't want to explain how to overload that methods.

    I want to do 2 methods to serialize and deserialize the object. Few days ago i have asked on this forum about serialization. I was anwered how to do this.
    And i had coded 2 methods to do this. But that are methods in different external class.

    Now i want these 2 methods are my root class methods. So the class can serialize itself and then deserialize with special constructor or method.

    first method works:
    Java Code:
    public String saveObject(){
            String sobj="";
             try{
                 
            ByteArrayOutputStream fos = new ByteArrayOutputStream();
            ObjectOutputStream outStream = new ObjectOutputStream( fos );
            outStream.writeObject( this );
            
            outStream.flush();
            sobj=fos.toString();
             
            }
            catch (IOException e) { 
               this.error=1;
               //System.out.print("\nerror1: "+e.toString());
            }
            return sobj;
        }
    i can use it
    Java Code:
     String sobj="";
              MyTest2 a=new MyTest2();
              a.setData("bla");//some method that changes properties
              sobj=a.saveObject();
              System.out.print("\nlog2: "+sobj);
    there is no problem. but i can't restore object.
    first i tried to do
    Java Code:
     public boolean restoreObject(String sobj){
            try{
                ByteArrayInputStream input = new ByteArrayInputStream(sobj.getBytes());
                ObjectInput oi = new ObjectInputStream(input);
                this=oi.readObject();
                oi.close();
                
            }
           catch
    ......
            return true;
        }
    but line this=oi.readObject(); has error. because variable this is final.

    so i tried different way
    Java Code:
    public MyTest1 restoreObject(String sobj){
            Class a=this.getClass();
            Object b;  
            try{
                b=a.newInstance();
                ByteArrayInputStream input = new ByteArrayInputStream(sobj.getBytes());
                ObjectInput oi = new ObjectInputStream(input);
                 
                b=oi.readObject();
                oi.close();
                
            }
            catch (IOException e) { 
               ....
               ....
            return b;
        }
    and use it
    Java Code:
    MyTest1 b=new MyTest1();
    b=b.restoreObject(sobj);
    and it works for root class MyTest1. but doesn't works for MyTest2.

    i tried some modifications
    like
    Java Code:
    public Object restoreObject(String sobj)
    and it works if
    Java Code:
    b=(MyTest2)b.restoreObject(sobj);
    but i don't want to write (MyTest2) each time.

    Is there way to solve this?
    If you think that it is not difficult to write (MyTest2) each time i will explain why i can't do this.

  9. #9
    georgemc is offline Senior Member
    Join Date
    Sep 2008
    Posts
    135
    Rep Power
    0

    Default

    Since ObjectInputStream returns an Object, you've got little option but to do the casts, one way or another. Presumably it's only some classes you want to add this behaviour to, so you could use generics to avoid writing the methods out over and over again, but what you're really talking about is a factory method, which needs to be static, otherwise you're in the bizarre situation of having to create instances of your classes simply in order to create other instances of your classes. So the answer to your question is, you can't avoid the repetitive code this way. The solution to your problem, though, is to use some other, external class to serialize and de-serialize your objects for you. There's actually little benefit to having "self-serializing" classes anyway.

    By the way, using inheritance simply to avoid having to type methods out over and over again is a poor use of inheritance, and you'll quickly find yourself fixing really awkward bugs if you go down that route. A good number of the awkward bugs I fix are a direct result of people misusing inheritance like that, and you'll quickly make enemies of your fellow developers that way! Google "favour composition over inheritance" for more details on that

  10. #10
    georgemc is offline Senior Member
    Join Date
    Sep 2008
    Posts
    135
    Rep Power
    0

    Default

    In fact, a bug I'm looking at right now should be utterly trivial - a button is missing from somewhere - but it's proving tricky to fix, exactly because there are something like 15 subclasses all dependent on one another. Inheriting from classes should be avoided in most cases, really

  11. #11
    Gelembjuk is offline Member
    Join Date
    Oct 2008
    Posts
    9
    Rep Power
    0

    Default

    Ok. I will try to do another class to make serialisation.

    Can you explain what is difference beetwean extends and implements?
    class C2 extends C1
    class C2 implements C1

Similar Threads

  1. Server returned HTTP response code: 500.. i need help
    By hardc0d3r in forum Java Servlet
    Replies: 9
    Last Post: 03-12-2012, 08:08 PM
  2. writting extended ascii chars on socket........or Endianness Issue......??
    By sachinj13 in forum Threads and Synchronization
    Replies: 8
    Last Post: 09-23-2008, 02:20 PM
  3. Replies: 1
    Last Post: 05-16-2008, 11:06 PM
  4. abstract extended and hiding variable??
    By Ace_Of_John in forum New To Java
    Replies: 5
    Last Post: 12-23-2007, 02:46 PM
  5. Server returned HTTP response code: 500
    By Heather in forum Java Servlet
    Replies: 1
    Last Post: 07-09-2007, 04:32 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •