interface can only have method signatures on it. It can't have implementations(body of methods) but abstract classes can have implementations. A class can be labeled as abstract even if no methods in the class are abstract. Abstract classes cannot be instantiated. If all the methods in a class are abstract it behaves like interface. Is it? Then why do we need interface? Only limitation of abstract classes is that they are classes which means we cannot extend from more than one abstract class.
What is the difference between static and not static methods?
Static methods can be accessed using class name while non static method requires instance of the class to access it. Both static and non static methods have single copy in the application. So under the hood what is the difference? One important distinction is that static methods cannot be virtual. Other is that static methods don't have access to this pointer. Non static methods take the object (on which it is called as argument). Static and non static methods look like this:
class X {
public static void staticMethod() {
//do sth
}
public void nonStaticMethod() {
//do sth
}
}
Under the hood the compiler generates method like this:
public void staticMethod() {
//do sth
}
public void nonStaticMethod(X this) {
//do sth
}
What is the difference between Comparable and Comparator ?
Comparable can be implemented by any class that requires ordering. compareTo method of the Comparable interface takes another object to which the current object is compared. For example you might have Person object and you have implemented Comparable to compare those objects using the first name and last name. But later your need changes and you have to order person objects based on their address. In this case, with Comparable, you have to change the implementation. You might not want to do that because you might need sorting using first name and last name in other places.So in that case you can always use Comparator interface. The sort method of Collections class can also take Comparator as argument. This helps you sort objects based on your needs. With comparable you are stuck to one implementation.
When do you have to override hashcode method?
When you will be using a hashed container to put your objects in, you need to override hashcode. If you override equals it's always good to override hashcode too. The hashcode provided by Object class in Java Language takes memory address of the object as hashcode. This is not what we want with our objects. For example consider following example:
class Person {
private String name;
private String dob;
public Person(String name, String dob) {
this.name = name;
this.dob = dob;
}
public boolean equals(Object obj) {
//implementation
}
//..
public static void main(String[] args) {
Set<Person> persons = new HashSet<Person>();
Person p1 = new Person("Person1", "12/12/2008");
persons.add(p1);
Person p2 = new Person("Person1", "12/12/2008");
if(persons.contains(p2)) {
//do sth
}
}
}
I am assuming here that person with same name and Date of Birth are equal. Do you think the condition will be true? Not necessarily. It's because the two person objects might get mapped into two different buckets in the hashset. Unless we return same hashcode for two equal objects there is no guarantee that the objects can be located in the hashed containers. So keep in mind that whenever you override equals you should override hashcode and two equal objects should always return same hashcode.