Since an abstract class can contain both complete and incomplete methods, when is it necessary to implement an interface? When should it implement an interface in an abstract class?
It is a standard way of how OOP works. Imagine a class Human. It is of course abstract as there can not be a concrete instance of a human. A concrete implementation could for example be a class Person that requires a name and some other information.
public class Person extends Human {
String name;
int age;
}
A common usage of interfaces is to describe abilities. In our example we could have interfaces like CanWalk, CanBreath, CanJump, NeedsWater, HasGender and so on. In such a case a Human could implement all of these interfaces, it would be perfectly fine.
public abstract class Human implements CanWalk,
CanBreath, CanJump, NeedsWater, HasGender {
...
}
Those interfaces now have methods, like
public interface HasGender {
String getGender();
}
and Human may implement them, but as an abstract human has no concrete gender, it may delegate the implementation to its implementing class Person:
public class Person extends Human {
String name;
int age;
String gender;
#Override
public String getGender() {
return gender;
}
}
On the other hand there might be interfaces where Human can offer an implementation, like
public interface NeedsWater {
int amountOfWaterNeeded();
void drink(int amount);
}
public abstract class Human implements CanWalk,
CanBreath, CanJump, NeedsWater, HasGender {
#Override
public int amountOfWaterNeeded() {
return 10;
}
}
Finally we may have classes that work with interfaces. Like
public class WaterDistributor {
public void distributeWaterTo(Iterable<NeedsWater> consumers) {
for (NeedsWater c : consumers) {
c.drink(c.amountOfWaterNeeded());
}
}
}
And you want to be able to pass your humans to that method, so you need to implement the interface.
Related
Suppose I want to unit test the following abstract class:
abstract class Fruit {
private int calories;
public Fruit(int calories) {
this.calories = calories;
}
int getCalories() {
return this.calories;
}
double getKilojoules() {
return this.calories * 4.184;
}
}
I agree that abstract classes and interfaces should not be tested - their implementations should, but what about concretely defined methods like simple getters like getCalories()?
Now some say that simple methods like getters should not be tested, but even then: what about methods like getKilojoules()?
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
I am designing an interface, for which I plan to to have an abstract class or skeletal class as per Effective Java(Joshua Bloch) Item 18: Prefer interfaces to abstract classes.
The reason is to guard future evolution of the interface from breaking the implementing classes.
As of today, I do not have any methods for which I want to provide a default implementation. Is this design okay?
Eg:
public interface Foo{
public List<Baz> getBazList();
public String getId();
public String getName();
}
public abstract class AbstractFoo implements Foo{
}
There is a simple but powerful test you can apply in this and similar cases.
Ask yourself this question: "How would I use this abstract class in my code? What do I plan to do with it that I can't with my interface?"
If the answer is "nothing", then get rid of it. If a construct serves no real purpose, it just adds clutter to your code.
If you think that the interface might be expanded in the future, thus rendering the child classes incompatible (since they do not implement those methods), using that empty abstract superclass might be a way to keep it able to compile easily.
I.e. today you have
public interface Foo{
public List<Baz> getBazList();
public String getId();
public String getName();
}
public abstract class AbstractFoo implements Foo{
}
public class Foo1 extends AbstractFoo {
public List<Baz> getBazList() { ... }
public String getId() { ... }
public String getName() { ... }
}
public class Foo2 extends AbstractFoo {
public List<Baz> getBazList() { ... }
public String getId() { ... }
public String getName() { ... }
}
In the future, someone changes the interface (for whatever reason), so you do the following:
// extended
public interface Foo{
public List<Baz> getBazList();
public String getId();
public String getName();
public void breakMyCode();
}
// provide dummy implementation for breakMyCode()
public abstract class AbstractFoo implements Foo{
public void breakMyCode() {
throw new RuntimeException("not implemented");
}
}
// unchanged
public class Foo1 extends AbstractFoo {
public List<Baz> getBazList() { ... }
public String getId() { ... }
public String getName() { ... }
}
// unchanged
public class Foo2 extends AbstractFoo {
public List<Baz> getBazList() { ... }
public String getId() { ... }
public String getName() { ... }
}
Is this a good idea? Not really. When the interface gets extended, there is probably a reason for it, and just providing a dummy implementation that either does nothing or throws a RuntimeException doesn't make the program work as expected. It's rather a way to hide ommissions during compile but let them break the program during runtime.
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
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.