简体   繁体   中英

Abstract superclass passing supertype to return type

I'm trying to figure out how to (if it's even possible) change the base return type, when the type has yet to be passed to an abstract class. (I'm sorry for such a bland explanation, but I really have no clue how to better explain this)

// Base Profile and Repository
public abstract class BaseProfile { }
public abstract class BaseRepository<T extends BaseProfile> {
    public abstract T doSomething(String name);
}

// Enhanced Profile and Repository
public abstract class EnhancedProfile extends BaseProfile {
    public abstract String getName();
}
public abstract class EnhancedRepository<T extends EnhancedProfile> extends BaseRepository<T> {
}

// Instance of Repository
public class InstanceProfile extends EnhancedProfile {
    @Override
    public String getName() { return "Hello World"; }
}
public class InstanceRepository extends EnhancedRepository<EnhancedProfile> {
    public EnhancedProfile doSomething() { return null; }
}

Now what I want is to store an EnhancedRepository without knowing it's inherited class and be able to access the EnhancedProfile, not BaseProfile, see below:

// What I want
EnhancedRepository repo = new InstanceRepository();
EnhancedProfile enProfile = repo.doSomething();
// Does not work because the doSomething() method actually returns
// BaseProfile, when I need it to at least return the EnhancedProfile

// What I know works, but can't do
EnhancedRepository<InstanceProfile> repo2 = new InstanceRepository();
EnhancedProfile enProfile2 = repo2.doSomething();
// This works because I pass the supertype, but I can't do this because I need
// to be able to access EnhancedProfile from the doSomething() method
// from a location in my project which has no access to InstanceProfile

How can I get the EnhancedProfile from doSomething(), instead of the base-most type BaseProfile, without knowing the supertype of EnhancedRepository?

One simple way is to not use generics (seems pointless in your example). Instead override the method with a more specific one

// Base Profile and Repository
public abstract class BaseProfile {
}

public abstract class BaseRepository {
    public abstract BaseProfile doSomething(String name);
}

// Enhanced Profile and Repository
public abstract class EnhancedProfile extends BaseProfile {
    public abstract String getName();
}

public abstract class EnhancedRepository extends BaseRepository {
    @Override
    public abstract EnhancedProfile doSomething(String name);
}

// Instance of Repository
public class InstanceProfile extends EnhancedProfile {
    @Override
    public String getName() {
        return "Hello World";
    }
}

public class InstanceRepository extends EnhancedRepository {
    public EnhancedProfile doSomething(String name) {
        return null;
    }
}

void whatIWant() {
    EnhancedRepository repo = new InstanceRepository();
    EnhancedProfile enProfile = repo.doSomething("");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM