Reputation: 1775
I am modifying a sample class from a book and trying to convert it to use generics to help me learn how it works. You can see my code below where I made an attempt. The generic A, B, and C used to be String String and int.
public class Student<A,B,C> implements Person {
A id;
B name;
C age;
public Student(A i, B n, C a) {
id = i;
name = n;
age = a;
}
protected int studyHours() {return age/2;}
public A getID() {return id;}
public B getName() {return name;}
public C getAge() {return age;}
public boolean equals(Person other) {
if(!(other instanceof Student)) return false;
Student s = (Student) other;
return id.equals(s.id);
}
public String toString() {
return "Student(ID: " + id + ", Name: " + name + ", Age: " + age + ")";
}
public static void main(String[] var0) {
Student<String,String,int> studentOne = new Student("123", "Guillermo", 34);
Student<String,String,int> studentTwo = new Student("345", "Cheryl", 35);
int numberOfStudyHours;
numberOfStudyHours = studentOne.studyHours();
System.out.println("Guillermo studies " +numberOfStudyHours+ " hours");
}
}
The Person Interface is below
public interface Person {
public boolean equals(Person other); //is this the same person?
public String getName();
public int getAge();
}
Your expert guidance would be greatly appreciated. I am getting this error:
Student.java:4: error: Student is not abstract and does not override abstract method getAge() in Person
public class Student<A,B,C> implements Person {
^
Student.java:18: error: getAge() in Student cannot implement getAge() in Person
public C getAge() {return age;}
^
return type C is not compatible with int
where C is a type-variable:
C extends Object declared in class Student
Student.java:17: error: getName() in Student cannot implement getName() in Person
public B getName() {return name;}
^
return type B is not compatible with String
where B is a type-variable:
B extends Object declared in class Student
Student.java:15: error: bad operand types for binary operator '/'
protected int studyHours() {return age/2;}
^
first type: C
second type: int
where C is a type-variable:
C extends Object declared in class Student
Student.java:28: error: unexpected type
Student<String,String,int> studentOne = new Student("123", "Guillermo", 34);
^
required: reference
found: int
Student.java:29: error: unexpected type
Student<String,String,int> studentTwo = new Student("345", "Cheryl", 35);
^
required: reference
found: int
Upvotes: 2
Views: 221
Reputation: 5353
For some better examples of where generics make sense, look through the various Java Collections classes. For instance, it can make sense to make a Map from anything to anything else (String to Integer, Integer to String, Integer to Integer, Person to String). You want only one class to implement all those maps, but by instantiating each map with its types,
Map<Person,Person> motherMap = new HashMap<>();
the compiler and IDE know what kind of key has to be given to the get()
method, and what type the result will be, preventing a lot of coding errors at the get-go.
Another place to look for examples where generics are used to good effect is the google libraries: see GuavaExplained.
For a practice exercise, you could try implementing a binary tree with left and right child nodes, where the tree nodes are all of the same generic type T.
For the compilation error, Generics cannot be used for primitive types—the lowercase ones like boolean and int—though you can use Boolean and Integer instead. Also, the interface would typically be generic as well: HashMap<K,V> implements Map<K,V>
Upvotes: 1
Reputation: 3823
For your example it looks like you should change your interface to:
public interface Person<B,C> {
public boolean equals(Person other); //is this the same person?
public B getName();
public C getAge();
}
and then
public class Student<A,B,C> implements Person<B,C> {
A id;
B name;
C age;
...
}
But this isn't really a good use of generics. Also keep in mind you can't use int
or other primitives with generics. You have to use Integer
or the other boxing classes.
Upvotes: 0