質問

I have this:

public interface IDongle {
    public abstract boolean connect();
}

public abstract class DongleManager {

    private boolean connected = false;
    public void setConnected(boolean status) {
        connected = status;
    }
    public boolean getConnected() {
        return connected;
    }
}
public class SimulatedDongle extends DongleManager implements IDongle {
{
    @Override
    public boolean connect() {
        // ...
        return true;
    }
}

public class RealDongle extends DongleManager implements IDongle {
{
    @Override
    public boolean connect() {
        // ...
        return true;
    }
}

How should I create a instance of SimulatedDongle which I can access all of its methods?
e.g

DongleManager dongle = new DongleSimulator();
dongle.getConnected();
dongle.connect(); // Erorr!!  

or

IDongle dongle = new DongleSimulator();
dongle.getConnected(); // Error!!
dongle.connect();
役に立ちましたか?

解決

Make DongleManager to implement interface IDongle.

public abstract class DongleManager implements IDongle {

  private boolean connected = false;
  public void setConnected(boolean status) {
      connected = status;
  }
  public boolean getConnected() {
      return connected;
  }
}

他のヒント

First case,

DongleManager dongle = new SimulatedDongle();
dongle.getConnected();
dongle.connect(); // Erorr!! 

It fails in the connect because, you can only override methods which are defined in the parent class. In this case, DongleManager doesn't have connect. So, it fails.

Second case,

IDongle dongle = new SimulatedDongle();
dongle.getConnected(); // Error!!
dongle.connect();

You are assigning an object of DongleSimulator to IDongle reference, which has only connect defined in it, not getConnected. That is why it fails.

I would recommend designing your system, like this

interface IDongle {
    public abstract boolean connect();
}

abstract class DongleManager implements IDongle {

    private boolean connected = false;
    public void setConnected(boolean status) {
        connected = status;
    }
    public boolean getConnected() {
        return connected;
    }
}

class SimulatedDongle extends DongleManager {
    @Override
    public boolean connect() {
        return true;
    }
}

class RealDongle extends DongleManager {
    @Override
    public boolean connect() {
        return true;
    }
}

If you look at the DongleManager, it implements IDongle and the children of this class only extend DongleManager.

Live Demo of the working solution

Note: Since getConnected is defined only in DongleManager, IDongle interface will not have any idea about it. So, the following will still fail.

    IDongle dongle = new SimulatedDongle();
    dongle.getConnected();
    //  error: cannot find symbol
    dongle.connect();

If you want to make that possible, then you need to include that also in the IDongle, like this

interface IDongle {
    public abstract boolean connect();
    public boolean getConnected();
}

both are not satisfying the required method access

 Tips of overriding methods

1)In order to execute any code  it has to be passed in 2 phase
a)compile time
b)runtime

At compile time, only reference variable(ie left side of = in your case
DongleManager dongle = new DongleSimulator(); it is dongle of type DongleManager) 
will decide what method has to be called and compiler checks for such methods
inside reference variable type.
if not available then compile time error is thrown.

At runtime ,the object assigned to reference variable(ie right side of =,
in your case DongleManager dongle = new DongleSimulator(); it is DongleSimulator)
will be looking for method inside its type.

it looks for the method overriden inside object (not variable left side of =)

consider below case

    DongleManager dongle = new DongleSimulator();
    dongle.getConnected();
    dongle.connect(); // Erorr!!  

    here dongle.getConnected(); works well because getConnected() method available at compile time with DongleManager.

    dongle.connect(); fails because at compile time itself connect() method is not available with DongleManager so compile time error.

    second scenario

    IDongle dongle = new DongleSimulator();
    dongle.getConnected(); // Error!!
    dongle.connect();

    here
    dongle.getConnected(); // error because IDongle at compile time not having getConnected() method

    dongle.connect();//success because IDongle is having method at compile time and at run time it calls DongleSimulator overriden connect() method.

    so to get all methods as per your requirement. create a hierarchy in such a way it shoud have parent->child1->chid2 so that using parent you can access all parent's methods and child's overriden methods.

so it should be as below

    interface IDongle {
        public abstract boolean connect();
    }

    abstract class DongleManager implements IDongle {

        private boolean connected = false;
        public void setConnected(boolean status) {
            connected = status;
        }
        public boolean getConnected() {
            return connected;
        }
    }

    class SimulatedDongle extends DongleManager {
        @Override
        public boolean connect() {
            return true;
        }
    }

    class RealDongle extends DongleManager {
        @Override
        public boolean connect() {
            return true;
        }
    }

Now interface method is available inside abstract class and hence
using its reference variable we can call that method along with 
its own method as well.

Try

DongleSimulator dongle = new DongleSimulator();
dongle.getConnected();
dongle.connect();

Update

If you want to get flexibility when using interfaces, you should write code like this:

IDongle.java

public interface IDongle {
    public boolean connect();

    public boolean getConnected();

    public void setConnected(boolean status);
}

DongleManager.java

public abstract class DongleManager implements IDongle {

    private boolean connected = false;

    @Override
    public boolean getConnected() {
        return connected;
    }

    @Override
    public void setConnected(boolean status) {
        connected = status;
    }
}

SimulatedDongle.java

public class SimulatedDongle extends DongleManager implements IDongle {
    @Override
    public boolean connect(){
    // ...
    return true;
}

There isn't error.

public static void main(String[] args) throws IOException {

    IDongle dongleManager = new SimulatedDongle();
    dongleManager.connect();
    dongleManager.getConnected();
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top