I'm working on a simple project using Interfaces, but I am having an issue making my class conform to the interface.
My thought process is that since Article implements IDedObject, I should be able to pass an Article as a parameter in my overridden functions within my Article Class definition. Unfortunately this throws the error "The type Article must implement the inherited abstract method IDedObject.getID()"
Interface
public interface IDedObject{
public int getID(IDedObject object);
public void printID(IDedObject object);
}
Class
public class Article implements IDedObject{
private int articleID;
private String articleName;
private String authorName;
#Override
public int getID(Article article){
return article.articleID;
}
#Override
public void printID(Article article){
System.out.println(article.articleID);
}
}
What is missing or incorrect?
Only a guess since we don't have your requirements, but I think that your interface is broken, that your methods shouldn't require parameters much less parameters of its own type. Consider changing:
public interface IDedObject{
public int getID(IDedObject object);
public void printID(IDedObject object);
}
to:
public interface IDedObject{
public int getID();
public void printID();
}
Then the implementation would be trivial
public class Article implements IDedObject{
private int articleID;
private String articleName;
private String authorName;
// constructor and other getter and setter methods here
#Override
public int getID(){
return articleID;
}
#Override
public void printID(){
System.out.println("" + articleID);
}
}
As for your compiler error -- the signature of any overridden methods must match those of the interface methods. So for instance in your Rectangle example in your link, if you extend that class or interface, then the method parameter must take the interface parameter as declared in the interface.
For example, say you had the following interface:
public interface FooInterface {
int getValue();
void printValue();
int difference(FooInterface fi);
}
The concrete class that implements this interface must use a FooInterface parameter for the difference method. For example:
class FooClass implements FooInterface {
private int value;
#Override
public int getValue() {
return this.value;
}
#Override
public void printValue() {
System.out.println(String.valueOf(value));
}
#Override // can't use FooClass for parameter here
public int difference(FooInterface fi) {
return value - fi.getValue();
}
}
The getID and putID methods are not being overriden in Article class. They are being overloaded.
When you change the parameter type, it is an overload and not an override. This may seem a bit confusing at first but the key thing to understand is that Article inherits the two methods from the interface. When you change the parameter type, you are actually overloading these inherited methods rather than overriding them.
That said, the purpose of a getter method is to return the value of an instance variable and optionally perform some operations on this value before returning it.
Your override
public int getID(Article article)
Doesn't override the method of the interface because of a mismatch in the parameter - it should be IDedObject.
You could use a generic parameter to IDedObject, and use a wildcard constraint to make sure it implements IDedObject, but as far as I know, there is no way to tell Java that you want to inherit with the same type as the wildcard.
You need to cast to the implementation of the interface (Article). The method signatures in the interface and the class need to be the same.
public interface IDedObject{
public int getID(IDedObject object);
public void printID(IDedObject object);
}
public class Article implements IDedObject{
private int articleID;
private String articleName;
private String authorName;
#Override
public int getID(IDedObject object) {
Article article = (Article) object;
return article.articleID;
}
#Override
public void printID(IDedObject object) {
Article article = (Article) object;
System.out.println(article.articleID);
}
}
Related
My sample code structure is like this. There is one parent class Building and one subclass House.
Buiding
public class Building {
private String name;
private int noOfHouses;
}
House
public class House extends Building {
private String houseNumber;
}
I want to write a generic method so that i can access the subclass method also.
something like this.
public <T> void construct(T a){
System.out.println(a.getHouseNumber());
}
Please help.
In fact your example does not show the need of generics. You can use:
public static void construct(House a){
System.out.println(a.getHouseNumber());
}
The same thing, unnecessarily complicated to use generics would also work fine:
public static <T extends House> void construct(T a){
System.out.println(a.getHouseNumber());
}
You can't, and shouldn't do that. It's a bad idea to make parent classes aware of child classes' own concrete methods.
You can use a bounded parameter, if this method is in House, or any other class that doesn't complicate the parent/child relationship:
public static <T extends House> void construct(T a){
System.out.println(a.getHouseNumber());
}
The same thing can be done if the parent is abstract, as suggested above:
public abstract class Building {
private String name;
private int noOfHouses;
public abstract String getHouseNumber();
public static <T extends Building> void construct(T a){
System.out.println(a.getHouseNumber());
}
}
Note that the parent doesn't have to be abstract, as long as it's OK with your design
Generics have nothing to do with this problem. Java provides you with the facility of RunTimePolymorphism, but you can't invoke child's specific method using parent reference.
Consider the following case:
Building b = new House(); //Fine
b.getHouseNumber() // Compiler will be happy only if getHouseNumber is in Building.
I agree with Ernest Kiwele, but if you want to access a method that will be part of a subclass you can override a method in each subclass
abstract class Building{
private String name;
private int noOfHouses;
public abstract String getHouseNumber();
public void construct(){
System.out.println( getHouseNumber() );
}
}
public class House extends Building{
private String houseNumber = "houseNumber";
public String getHouseNumber(){
return this.houseNumber;
}
public static void main(String[] args){
House h = new House();
h.construct();
}
}
I don't know of this error and how to fix it. I'm getting this error with all of my child classes. Included the Error Message and the abstract method that needs to be over written. Added class and what is inside of class.
Error:
MyMath3 is not abstract and does not overide abstract method compareTo(Homework3) in java.lang.Compareable
Code:
public abstract class Homework3 implements Comparable<Homework3>
public class MyMath3 extends Homework3
private int page;
private String typeHomework;
/**
* Constructor for objects of class MyMath
*/
public MyMath3(int p)
{
}
public void createAssignment(int p)
{
typeHomework="Math";
page=p;
}
public String getHomework()
{
return typeHomework;
}
public int getPage()
{
return page;
}
public String toString()
{
return typeHomework+"--- The number of pages needed to read:"+page;
}
}
public int compareTo(Homework3 obj,Homework3 obj2 )
{
int compareResult= obj.compareTo(obj2);
return compareResult;
}
The signature of your compareTo method should be:
#Override
public int compareTo(final Homework3 other)
You can access your current object using... this!
By the way, you might run into some StackOverflowException in a few minutes/seconds...
That's because your compareTo method recursively calls itself. You probably meant to compare the number of pages needed to be read. If so, this could be the body of your compareTo implementation:
return this.getPage() - other.getPage();
Cheers ;)
I have five cases of enums that look like this one below:
public enum Answers{
A(0), B(1), C(2), D(3), E(4);
Answers(int code){
this.code = code;
}
protected int code;
public int getCode(){
return this.code;
}
}
They all are all virtually the same except consisting of different "codes" and enumerators. I now have this following class where the generic is an extension of an Enum, however, I need to be able to use the getCode(), which is only in my enums, not a basic enum.
public class test<T extends Enum>{
public void tester(T e){
System.out.println(e.getCode()); //I want to be able to do this,
//however, the basic enum does don't
//have this method, and enums can't extend
//anything.
}
}
Thank you
You can make your enums implement an interface:
public interface Coded {
int getCode();
}
Then:
public enum Answers implements Coded {
...
}
And:
public class Test<T extends Enum & Coded> {
public void tester(T e) {
System.out.println(e.getCode());
}
}
Make all your enums implement a common interface:
public interface HasCode {
int getCode();
}
public enum Answers implements HasCode {
...
}
And then
public class Test<T extends HasCode> {
Have your enum classes implement your own HasCode interface:
public interface HasCode {
public int getCode();
}
public enum Answers implements HasCode {
//...
Then you can restrict T to be a HasCode:
public class test<T extends HasCode>{
and then Java will recognize that anything, even an enum, as long it implements HasCode, will have a getCode() method and it can be called in tester.
If that is the only method you want to add to your Enum then you don't have to do it. Every Enum already has ordinal method which returns value that represents it position in Enum. Take a look at this example
enum Answers{
A,B,C,D,E;
}
class EnumTest<T extends Enum<T>>{
public void tester(T e){
System.out.println(e.ordinal());
}
public static void main(String[] args) throws Exception {
EnumTest<Answers> t = new EnumTest<>();
t.tester(Answers.A);
t.tester(Answers.B);
t.tester(Answers.E);
}
}
Output:
0
1
4
I am attempting to modify the behavior of my objects using the decorator pattern but have hit a bit of a snag where the decorator pattern seems to fail to be able to change the functionality of my objects the way I want.
Here is a simple example of what I am trying to do:
I have a class with a getter for an int and some other "complex" that does some computation using the getter
public class MyClass implements MyInterface {
private int value = 5;
#Override
public int getValue() {
return value;
}
#Override
public int complexStuff() {
return 50 + getValue();
}
}
I have an abstract decorator that just passes all the calls defined by the interface to a MyClass instance
public abstract class MyDecorator implements MyInterface {
private MyClass decorated;
public MyDecorator(MyClass decorated) {
this.decorated = decorated;
}
#Override
public int getValue() {
return decorated.getValue();
}
#Override
public int complexStuff() {
return decorated.complexStuff();
}
}
I want to be able to decorate a MyClass instance to modify the behaviour of the getValue() method in such a way that complexStuff() is also affected.
For example if I decorate a MyClass instance like this:
MyDecorator myDecorator = new MyDecorator(myClassInstance) {
#Override
public int getValue() {
return 100;
}
};
The way I have currently implemented this a call to myDecorator.getValue() would return 100, but a call to myDecorator.complexStuff() would return 55 as if the MyClass instance had not been decorated. What I want is for the call to myDecorator.complexStuff() to return 150.
Is there a way I can modify my use of the decorator pattern to achieve my desired result? Or some other pattern/solution I can use to get this to work how I want?
Thanks
If you can't modify MyClass, maybe you can derive from it and use the subclass instead? Then you can override getValue.
I don't think you can achieve this goal using a decorator pattern. You are trying to modify the behaviour of an existing instance, which isn't going to be trivial (if even possible).
Something like the following would work:
public class MyClass implements MyInterface {
private ValueProvider provider = new ValueProvider() {
#Override
public int getValue() {
return 5;
}
};
// (You may wish to include this method in MyInterface)
public void setValueProvider(ValueProvider provider) {
this.provider = provider;
}
#Override
public int getValue() {
return provider.getValue();
}
#Override
public int complexStuff() {
return 50 + getValue();
}
}
You can then substitute a different ValueProvider at runtime. A decorator class could do the substitution for you, if you want.
Your mistake is obvious. When you call MyDecorator.complexStuff() is delegate this call directly to the MyClass decorated delegate, where getValue() method is not overridden, because it is overridden in MyDecorator which is not MyClass. In other words, MyDecorator HAS-A MyClass, but NOT IS-A MyClass.
To fix your problem, just modify MyDecorator.complexStuff() method. Using this, you're free to override getValue() method, but no complexStuff() method:
abstract class MyDecorator implements MyInterface {
private final MyClass decorated;
public MyDecorator(MyClass decorated) {
this.decorated = decorated;
}
// this method is overridden, and returns 100 always
#Override
public int getValue() {
return decorated.getValue();
}
#Override
public final int complexStuff() {
return decorated.complexStuff() - decorated.getValue() + getValue();
}
}
I have a question about putting a Java enum in the interface.
To make it clearer, please see the following code:
public interface Thing{
public enum Number{
one(1), two(2), three(3);
private int value;
private Number(int value) {
this.value = value;
}
public int getValue(){
return value;
}
}
public Number getNumber();
public void method2();
...
}
I know that an interface consists of methods with empty bodies. However, the enum I used here needs a constructor and a method to get an associated value. In this example, the proposed interface will not just consist of methods with empty bodies. Is this implementation allowed?
I am not sure if I should put the enum class inside the interface or the class that implements this interface.
If I put the enum in the class that implements this interface, then the method public Number getNumber() needs to return the type of enum, which would force me to import the enum in the interface.
It's perfectly legal to have an enum declared inside an interface. In your situation the interface is just used as a namespace for the enum and nothing more. The interface is used normally wherever you use it.
Example for the Above Things are listed below :
public interface Currency {
enum CurrencyType {
RUPEE,
DOLLAR,
POUND
}
public void setCurrencyType(Currency.CurrencyType currencyVal);
}
public class Test {
Currency.CurrencyType currencyTypeVal = null;
private void doStuff() {
setCurrencyType(Currency.CurrencyType.RUPEE);
System.out.println("displaying: " + getCurrencyType().toString());
}
public Currency.CurrencyType getCurrencyType() {
return currencyTypeVal;
}
public void setCurrencyType(Currency.CurrencyType currencyTypeValue) {
currencyTypeVal = currencyTypeValue;
}
public static void main(String[] args) {
Test test = new Test();
test.doStuff();
}
}
In short, yes, this is okay.
The interface does not contain any method bodies; instead, it contains what you refer to as "empty bodies" and more commonly known as method signatures.
It does not matter that the enum is inside the interface.
Yes, it is legal. In a "real" situation Number would implement Thing, and Thing would probably have one or more empty methods.