One class implements from two different interfaces in Java - java

I have two classes that implements from two interfaces.
Here is my interfaces:
interface Identifiable {
int getId();
}
interface Greetable {
String helloMessage();
String byeMessage();
}
Here is my classes:
public class Lecturer implements Greetable, Identifiable {
private int employeeId;
private String name;
private String title;
#Override
public String helloMessage() {
return name;
}
#Override
public String byeMessage() {
return title;
}
}
public class Student implements Greetable, Identifiable {
private char examScore;
#Override
public String helloMessage() {
return "Hi";
}
#Override
public String byeMessage() {
return "Whats up";
}
}
I get the error from the classes that it has to abstract the methods from the interfaces? What does that mean?

Non-abstract classes are required to create concrete versions of any methods found in any interfaces that they're implementing, and while your classes implement concrete versions of one of the interface, the Greetable interface, you're not implementing all the methods of both interfaces, here the public int getId() method from the Identifiable interface is missing from both classes.
Solution: give both classes an int id field as well as the getId() method that returns the value held by this field.
e.g. for Student,
public class Student implements Greetable, Identifiable {
private char examScore;
private int id; // **** your classes will need this field ****
// need to set the ID somehow, either with a setter or a constructor
public Student(int id) {
this.id = id;
}
#Override
public String helloMessage() {
return "Hi";
}
#Override
public String byeMessage() {
return "Whats up";
}
#Override // **************** add this method to return the value held by id ******
public int getId() {
return this.id;
}
}

You define to implement both interfaces, but you only implemented the methods of the second interface.
So you have to implement the method getId() in both classes.

You havent implemeted the getId() method in Identifiable. If you are not implementing that method you need to make the Lecturer and Student as abstract or you need to implement the getId() method in both the classes.
In your case I think you will need to create instances of the Student and Lecturer. If so then you cannot make them as abstract, as abstract class instances cannot be created. So better implement the getId() in both the classes.

Your Student and Lecturer classes MUST implement both Greetable, Identifiable interface methods, otherwise they need to be declared as abstract classes i.e., you are missing getId() from Identifiable interface, which is causing the issues, corrected code below.
Lecturer class:
public class Lecturer implements Greetable, Identifiable {
int getId() {
return employeeId;
}
//all other existing methods
}
Student class:
public class Student implements Greetable, Identifiable {
int getId() {
return studentId;
}
//all other existing methods
}
You can look here

Related

Generic Enum Type for anything extended

I like to make a generic enum that accepts anything.
For this example I use TaskStatus, but in the future, I like to use Generic Enum for example; StudentStatus, this student status can take an id and description itself and it will convert automatically. Moreover, iterate every object and finally automatically return. Is there any chance I can make it?
#Getter
#AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum TaskStatusEnum{
READY(1, "Ready"),
ON_GOING (2,"On going");
private final long id;
private final String description;
public static TaskStatusEnum get (long id)
{
for (TaskStatusEnum status : TaskStatusEnum.values()) {
if (status.id == id) {
return id;
}
}
return null;
}
I'm not sure what exactly you want. You can use interface on enum, then you can use interface as status and dont care what exactly status class is.
public interface Status<E extends Enum<E> & Status<E>> {
public long getId();
public String getDescription();
}
student status:
public enum StudentStatus implements Status<StudentStatus>{
NEW(0, "new");
;
private long id;
private String description;
private StudentStatus(long id, String description) {
this.id=id;
this.description = description;
}
#Override
public long getId() {
return id;
}
#Override
public String getDescription() {
return description;
}
}
task status:
public enum TaskStatus implements Status<TaskStatus>{
OPEN(0, "open");
;
private long id;
private String description;
private TaskStatus(long id, String description) {
this.id=id;
this.description = description;
}
#Override
public long getId() {
return id;
}
#Override
public String getDescription() {
return description;
}
}
generic method to find out status by id
public abstract class StatusUtil {
public static <E extends Enum<E> & Status<E>> E get(Class<E> statusClass, long id) {
return Arrays.asList((E[]) statusClass.getEnumConstants())
.stream()
.filter(item -> item.getId() == id)
.findAny()
.orElse(null);
}
}
example how use:
public class Test {
public static void main(String... args) {
StudentStatus studentStatus = StatusUtil.get(StudentStatus.class, 0);
TaskStatus taskStatus = StatusUtil.get(TaskStatus.class, 0);
List<Status> statusList = Arrays.asList(studentStatus, taskStatus);
statusList.forEach(status -> System.out.println(status.getClass().getName()+"\t"+status.getId()+"\t"+status.getDescription()));
}
}
if you use JAVA below 8:
public interface Status<E extends Enum<E>> {
public long getId();
public String getDescription();
}
statusUtil:
public abstract class StatusUtil {
public static <E extends Enum<E>> E get(Class<E> statusClass, long id) {
for(E item: (E[]) statusClass.getEnumConstants()) {
if(item.getId() == id) {
return item;
}
}
return null;
}
}
test:
public static void main(String... args) {
StudentStatus studentStatus = StatusUtil.get(StudentStatus.class, 0);
TaskStatus taskStatus = StatusUtil.get(TaskStatus.class, 0);
List<Status> statusList = Arrays.asList(studentStatus, taskStatus);
for(Status status: statusList) {
System.out.println(status.getClass().getName()+"\t"+status.getId()+"\t"+status.getDescription());
}
}
This you can use in cases, when enums has this same methods and you need common interface
Your enum is effectively final (no subclass allowed)
Apparently you are asking if TaskStatus enum can be subclassed. For example making a StudentStatus that inherits from TaskStatus.
➥ No, enums in Java cannot be subclassed.
Your enum definition actually is a subclass of Enum. That happens in the background, magically handled by the compiler. The inheritance stops there. Your enum definition is effectively final, not allowing further subclasses.
An enum definition can implement an interface. Instances from multiple enum definitions can be treated as all being objects of the same interface. See Answer by Victor1125.
An enum in Java is a convenient way to automatically instantiate one or more name objects, to represent a limited set of values known at compile time. Those instances all pop into existence when their definition class is loaded by the Java classloader. Those objects remain in memory.
You cannot add more instances dynamically at runtime. The entire domain of the enum’s objects is defined at compile time. (Exception: Some crazy twisted reflection/introspection code may be able to create more instances, but I would not go there.)
If you want inheritance, or dynamically created instances, do not use enums. Use regular classes and subclasses, collected into sets or lists. The sets or lists can be marked (< … >) with generics to allow the superclass of their contained elements. For example Set< Animal > can contain objects of the subclasses Dog, Cat, and Bird.
By the way, you can now define an enum in 3 places: its own class, nested within another class, and now in Java 16 (previewed in Java 15), locally inside a method.
Tip: No need to put "Enum" within the name of your enum. Endeavor to invent names for your enum class and enum objects that read naturally. The fact that they happen to be an enum should fade into the background. For example: See Month (Month.JANUARY) and DayOfWeek (DayOfWeek.MONDAY).
How to handle null point on StatusUtil.class
StatusUtil:
public abstract class StatusUtil {
public static <E extends Enum<E>> E get(Class<E> statusClass, long id) {
for(E item: (E[]) statusClass.getEnumConstants()) {
if(item.getId() == id) {
return item;
}
}
return null;
}

How can I express object which should be 2 different classes at the same time

Today I had test in OOP and I was given the following task to code:
Imagine you have two classes: Employee (which represents being an employee) and Ninja (which represents being a Ninja). An Employee has both state and behaviour; a Ninja has only behavior. You need to represent an employee who is also a ninja (a common problem in the real world). By creating only one interface and only one class (NinjaEmployee), show how you can do this without having to copy method implementation code from either of the original classes. Test your code in main method
I did not really understand the problem well, but this is the solution I came with (I know it's not what was asked):
I created 4 classes except main. As Employee has state and behaviour I came up with this code:
public class Employee {
private int ID;
private String Name;
private double salary;
public Employee(int ID, String Name, double salary) {
this.ID = ID;
this.Name = Name;
this.salary = salary;
}
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void startWorking() {
System.out.println("Started Working");
}
}
Class ninja has only behaviour:
public class Ninja {
public Ninja(){}
public void moveNinja(){
System.out.println("Ninja moved");
}
}
Class NinjaEmployee:
public class NinjaEmployee extends Employee implements MyInterface {
public NinjaEmployee(int ID, String Name, double salary) {
super(ID, Name, salary);
}
public void moveNinja() {
System.out.println("Ninja Moved");
}
}
Interface which does not make sense in my code:
public interface MyInterface {
public void moveNinja();
public void startWorking();
}
Main class:
public static void main(String[] args){
MyInterface em = new NinjaEmployee(123,"Sandro",1000000);
em.moveNinja();
em.startWorking();
}
My question is following:
1) Specifically/Technically what was asked in test?
2) What would be correct approach/code for given problem?
Nice question.
The key point of the question is:
we should use one interface.
Ninja class should have some methods (not attributes).
So we should try to use these key point.
I provide a class diagram below:
First of all: We have Employee class and implement it like other simple classes. It has some implemented attributes and classes.
Secondly: We have an Interface named Ninja_Interface that have some method declarations about ninja. (moveNinja1 and moveNinja2)
Thirdly: Ninja Class that implemented (or Realized) Nijna_Interface and have some implementation of any method declarations in Ninja_Interface.
Fourthly: the NinjaEmployee class. It inherited from Employee. So it has all Employee's attributes and methods. Also it implements Ninja_Interface. So it should implements all Ninja_Interface methods declarations. On the other hand, NinjaEmployee have an instance of Ninja (notice that Ninja class implements all Ninja_Interface methods). So, In Ninja_Employee class, in implementation of Ninja_Interface methods, we can use Ninja instance methods to call.
For example some parts of NinjaEmployee is like below code:
private Ninja ninja=new Ninja();
public void moveNinja1()
{
ninja.moveNinja1();
}
public void moveNinja2()
{
ninja.moveNinja2();
}
Main question is: why Ninja class should have only some methods?
It is because of Ninja class is just the implementations of Ninja_Interface methods and there no need to have attributes. So instances of Ninja class are the same. So we can declare Ninja attribute in NinjaEmployee as static attribute.
Finally: we can add some attributes of ninja into NinjaEmployee class too.
I don't know correct answer (task is kinda not very strictly defined, there is some unclear moments), but i would do something like this:
public interface IAmNinja {
public void moveNinja();
}
public interface IAmEmployer {
public void startWorking();
}
public class NinjaEmployee implements IAmNinja, IAmEmployer {
private Ninja _ninja;
private Employer _employer;
public NinjaEmployee(int ID, String Name, double salary) {
_employer = new Employer(ID, Name, salary);
_ninja = new Ninja();
}
public void moveNinja() {
_ninja.moveNinja();
}
public void startWorking() {
_employer.startWorking();
}
}
You cant create 1 object of 2 class es
You can extend class so whenever child class is instantiated it calls parent class constructor
Then You can create object of another class in that constructor
Add employees in array and add option to add employee in ninja? 1.yes or 2.no?
if yes , add to ninja..then in main method print names of ninja using for loop one by one

How to pass a variable from 2 different POJOs?

I got 2 POJOs that are being passed to a HttpEntity and converted to json.
Before passing them i need a variable which is in both of the POJOs with different names because of the needs of the API so i cant change them.
What is the best way without casting and in terms of OOP also within the POJO definition like mentioned in Wikipedia?
Abstract pojo
public abstract class Pojo{
//some common variables
//setter getters
}
PojoOne
public class PojoOne extends Pojo{
private String id;
//setter getter for id
}
PojoTwo
public class PojoTwo extends Pojo{
private String identifier;
// setter getter for identifier
}
Class that
public class SomeOtherClass {
public void getIdForUse(Pojo pojo){
String s = pojo. // How should this be to have ability to get both id and identifier
}
}
Add a common method to the common superclass:
public abstract class Pojo {
public abstract String getId();
// some common variables
// setter getters
}
public class PojoOne extends Pojo {
private String id;
#Override
public String getId() {
return id;
}
//setter for id
}
public class PojoTwo extends Pojo {
private String identifier;
// setter getter for identifier
#Override
public String getId() {
return identifier;
}
}

Java wrapper class subclass of concrete type

Let's say I have a class person as follows:
public class Person {
String name;
int age;
}
and a number of subclasses such as
public class Student extends Person {
// extra fields and methods
}
public class Teacher extends Person {
// extra fields and methods
}
Now, consider that for some application I need to assign an integer id to each person instance, but I don't want to extend the Person interface to add the getId() there and a field to hold the id. A simple solution would be to use a wrapper like:
public class PersonWrapper extends Person {
public PersonWrapper(Person p, int id) { // assign the id and other fields }
public int getId() { return id; }
}
This way the client code still works with the Person interface and a wrapped person can be
treated as a person.
The problem with this approach is that PersonWrapper is a subclass of Person and not Teacher or Student, and such a code won't work:
Teacher t = new PersonWrapper(teacher, 1);
t.giveGrade();
Of course, it's possible to create concrete wrapper types for all subclasses of Person, but I was wondering if there is a more elegant solution. The ideal solution would be something like this:
public class PersonWrapper<T extends Person> extends T
so that any PersonWrapper is a subclass of the type it wraps, but it's not possible in Java and I
suspect such definition may not be possible in any language.
In any case, how can I assign ids to subclasses without changing my client code that works with person and its subclasses, without creating a concrete wrapper for each subclass?
A wrapper does not necessarily need to extend to the class it's wrapping. So, just use PersonWrapper<T extends Person>:
public class PersonWrapper<T extends Person> {
T person;
int id;
public PersonWrapper(T person, int id) {
this.person = person;
this.id = id;
}
//getters and setters...
}
Also, a class can only extend from another class at compile time, so it's not possible that this PersonWrapper could extend from Student and Teacher at the same time, which makes impossible what you're looking for.
The only solution would be creating proxy classes on the fly using a library like cglib. For example, Spring creates proxies for classes when needs to add functionality on the fly to a class e.g. adding transaction management for methods or whole class.
The common solution to this problem is to make Person an interface.
interface Person {
public String getName();
public int getAge();
}
class ActualPerson implements Person {
private final String name;
private final int age;
ActualPerson(String name, int age) {
this.name = name;
this.age = age;
}
#Override
public String getName() {
return name;
}
#Override
public int getAge() {
return age;
}
}
class PersonWithId implements Person {
private final Person person;
private final int id;
PersonWithId(Person person, int id) {
this.person = person;
this.id = id;
}
#Override
public String getName() {
return person.getName();
}
#Override
public int getAge() {
return person.getAge();
}
}
Do not fear lots of code - the time you take writing code is insignificant compared to the time you spend regretting you didn't do it properly in the first place. Old Curmudgeon 2014
You're right that you can't do what you want to do. Assuming that you can't change the concrete classes to be, say, Student extends Person implements Identifiable, your best bet is to treat your wrapper really as a wrapper, and have a getter that returns its different elements:
public class Wrapper<T> {
private final T item;
private final int id;
...
public int getId() { return id }
public T getItem() { return item; }
}
This is a bit cumbersome to use, because you have to do something like wrapper.getItem().giveGrade() instead of just wrapper.giveGrade(). It also means you can't shove the wrapper into a List<Teacher> and then later downcast it to TeacherWrapper -- but that's a bit fragile, and there are often better ways to accomplish what you want. For most cases, this "pure" wrapper approach will do what you want.
Note that I didn't even have T extends Person. If the wrapper class doesn't need to use any Person methods, there's not much to gain from artificially restrict the generic. The call sites will all have the restriction either way. The one difference is that if a call site has a Wrapper<?>, then my code will only let you get the item as an Object, whereas the more restrictive T extends Person will let you get that item as a Person.
I hope I'm not missing something, but it appears to me that the wrapper pattern solves your problem:
public class Person implements IPerson{
String name;
int age;
public static void main(String[] args)
{
Teacher teacherWithID = new Teacher(new PersonWithID(new Person()));
Teacher teacherWithoutID = new Teacher(new Person());
}
}
interface IPerson{}
class Teacher implements IPerson{
public Teacher(IPerson personToBeWrapped){}
}
class Student implements IPerson{
public Student(IPerson personToBeWrapped){}
}
class PersonWithID implements IPerson{
public PersonWithID(IPerson personToBeWrapped){}
}
Whatever type your variable is should be the last wrapper.
The wrapper pattern can be considered to be a mechanic that allows you to "extend" classes at runtime. It's also called the decorator for that reason. You have competing inheritance mechanics in your code. (the built in one and the pattern) The result is that you cannot type your variable.
If you use the pattern exclusively, it works.

Java, how to inherit methods from abstract class

I have an abstract class Person and and interface comparable, which is also used for some other part of the program. Currently I have a method compareTo() in Person. When I try to compile, I get :
The type Student must implement the inherited abstract method
Comparable<Person>.compareTo(Person, Person)
What exactly do I have to do? I don't wont to implement this method in any of the subclasses, because I need this method for all of them, Student, Tutor, Professor, etc... Is there a better way of doing this?
Interface:
interface Comparable<Element> {
public int compareTo(Element nodeA, Element nodeB);
}
Abstract class Person:
abstract class Person implements Comparable<Person> {
protected String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String newName) {
name = newName;
}
public String toString() {
return name;
}
public int compareTo(Person personB) {
int comp = this.name.compareTo(personB.getName());
return comp;
}
}
And class Student
class Student extends Person implements Comparable<Person> {
private int id;
public Student(String name, int id) {
super(name);
this.id = id;
}
public int getID() {
return id;
}
public void setID(int newID) {
id = newID;
}
public String toString() {
return id + ", " + name;
}
}
Change your interface from:
interface Comparable<Element>
{
public int compareTo(Element nodeA, Element nodeB);
}
to:
interface Comparable<Element>
{
public int compareTo(Element nodeA);
}
And make your Person class be defined as:
abstract class Person implements Comparable<? extends Person> { /* ... */ }
And make your Student (and other Person-subclasses be):
class Student extends Person { /* ... */ }
That is all.
Your Comparable interface has a method compareTo(Element nodeA, Element nodeB). This method is not defined in Student, and it's not defined in Person either. Person has the following method:
public int compareTo(Person personB)
, which doesn't override compareTo(Person nodeA, Person nodeB)
Why are you redefining the standard java.util.Comparable interface?
You should implement the method as it appears in the interface, i.e. with two arguments
public int compareTo(Person nodeA, Person nodeB)
To avoid such problems in the future use the #Override annotation:
#Override
public int compareTo(Person nodeA, Person nodeB)
This will cause a compilation error if you try to override a method, but make a mistake in its signature.
Also, consider using Java's standard Comparable.
Your Comparable<Element> class declares a method public int compareTo(Element nodeA, Element nodeB);, but in your Person class, you implement public int compareTo(Person personB), which is not the same method signature.
You need to either implement public int compareTo(Person personA, Person personB), or alter your Comparable<Element> class's method definition to be public int compareTo(Element other); to override the core Comparable class's compareTo method.
Also, as #murat mentions below in the comment, using the #Override annotation would help you out (assuming you're on Java version 1.5 or higher). If you add #Override to a method that you're not actually overriding from a superclass (such as your two-argument compareTo method), then it will be a compiler error.
You need to implement
public int compareTo(Person nodeA, Person nodeB)
In your Person class. Currently you only have:
public int compareTo(Person personB)
You need to create a compareTo method in the Student class.
interface Comparable<Element> {
public int compareTo(Element nodeA, Element nodeB);
}
It makes sense if it was either:
interface Comparator<Element> { //comparator compares two instances of same type
public int compare(Element nodeA, Element nodeB);
}
or (has to be something like this for your case):
interface Comparable<Element> { //comparable compares itself with another instance of same type
public int compareTo(Element that);
}
But for both cases, you should use the standard Java interfaces: Even though you are only using Comparable also see Comparator.

Categories