Oops Try Again Did You Call the Namestring Function
Object-oriented programming offers a sustainable way to write spaghetti code. Information technology lets you accrete programs as a serial of patches.
― Paul Graham
Fundamentals of object-oriented programming
Object-oriented programming is a programming paradigm where everything is represented every bit an object.
Objects pass messages to each other. Each object decides what to do with a received message. OOP focuses on each object's states and behaviors.
What Are Objects?
An object is an entity that has states and behaviors.
For example, dog, cat, and vehicle. To illustrate, a canis familiaris has states like age, color, name, and behaviors like eating, sleeping, and running.
State tells us how the object looks or what properties it has.
Beliefs tells us what the object does.
Nosotros can actually represent a real world dog in a program as a software object by defining its states and behaviors.
Software objects are the actual representation of real earth objects. Retentiveness is allocated in RAM whenever creating a logical object.
An object is also referred to an example of a class. Instantiating a class means the same affair as creating an object.
The important matter to remember when creating an object is: the reference blazon should exist the same type or a super type of the object type. We'll encounter what a reference type is later in this article.
What Are Classes?
A class is a template or blueprint from which objects are created.
Imagine a form equally a cookie-cutter and objects equally cookies.
Classes define states as instance variables and behaviors equally instance methods.
Instance variables are also known as member variables.
Classes don't swallow whatever space.
To give you an idea about classes and objects, let'south create a Cat class that represents states and behaviors of real world Cat.
public class Cat { /* Case variables: states of Cat */ String name; int age; String colour; String brood; /* Instance methods: behaviors of True cat */ void slumber(){ System.out.println("Sleeping"); } void play(){ System.out.println("Playing"); } void feed(){ System.out.println("Eating"); } } Now nosotros have successfully divers a template for Cat. Let's say we have two cats named Thor and Rambo.
How can we define them in our program?
First, we need to create two objects of the True cat class.
public course Master { public static void chief(String[] args) { True cat thor = new Cat(); True cat rambo = new True cat(); } } Next, nosotros'll define their states and behaviors.
public class Main { public static void primary(String[] args) { /* Creating objects */ Cat thor = new Cat(); Cat rambo = new Cat(); /* Defining Thor cat */ thor.name = "Thor"; thor.age = three; thor.breed = "Russian Blue"; thor.colour = "Brown"; thor.sleep(); /* Defining Rambo true cat */ rambo.name = "Rambo"; rambo.historic period = 4; rambo.brood = "Maine Coon"; rambo.color = "Brown"; rambo.play(); } } Like the above code examples, we can ascertain our form, instantiate information technology (create objects) and specify the states and behaviors for those objects.
Now, nosotros take covered the basics of object-oriented programming. Let'south move on to the principles of object-oriented programming.
Principles of object-oriented programming
These are the four chief principles of the object-oriented programming paradigm. Understanding them is essential to becoming a successful programmer.
- Encapsulation
- Inheritance
- Abstraction
- Polymorphism
Now let'southward look at each in more detail.
Encapsulation
Encapsulation is a process of wrapping code and information together into a unmarried unit.
It's simply like a capsule that contains a mix of several medicines, and is a technique that helps keep example variables protected.
This can exist accomplished by using private access modifiers that tin't exist accessed by annihilation outside the form. In order to access private states safely, we take to provide public getter and setter methods. (In Java, these methods should follow JavaBeans naming standards.)
Let's say there is a record store that sells music albums of unlike artists and a stock keeper who manages them.
If you expect at figure four, the StockKeeper class can access the Anthology class'due south states directly as Album class's states are set to public.
What if the stock keeper creates an anthology and sets states to negative values? This can be done intentionally or unintentionally by a stock keeper.
To illustrate, let'due south meet a sample Coffee plan that explains the higher up diagram and statement.
Album course:
public form Album { public Cord name; public String artist; public double price; public int numberOfCopies; public void sellCopies(){ if(numberOfCopies > 0){ numberOfCopies--; System.out.println("1 album has sold!"); } else{ System.out.println("No more albums available!"); } } public void orderCopies(int num){ numberOfCopies += num; } } StockKeeper class:
public grade StockKeeper { public String name; public StockKeeper(String name){ this.proper noun = name; } public void manageAlbum(Album anthology, String proper noun, String artist, double price, int numberOfCopies){ /* Defining states and behaviors for anthology */ album.proper noun = name; anthology.artist = artist; anthology.price = price; anthology.numberOfCopies = numberOfCopies; /* Press album details */ System.out.println("Album managed by :"+ this.proper noun); Organisation.out.println("Album details::::::::::"); System.out.println("Anthology name : " + album.proper noun); Organisation.out.println("Album artist : " + album.artist); System.out.println("Album cost : " + album.price); Arrangement.out.println("Album number of copies : " + anthology.numberOfCopies); } } Master class:
public class Primary { public static void chief(String[] args) { StockKeeper johnDoe = new StockKeeper("John Doe"); /* Stock keeper creates album and assigns negative values for price and number of copies available */ johnDoe.manageAlbum(new Anthology(), "Glace When Moisture", "Bon Jovi", -1000.00, -l); } } Output:
Anthology managed by :John Doe Anthology details:::::::::: Anthology name : Slippery When Wet Anthology artist : Bon Jovi Album price : -1000.0 Album number of copies : -fifty The anthology's price and number of copies can't be negative values. How can we avoid this situation? This is where we use encapsulation.
In this scenario, we can cake the stock keeper from assigning negative values. If they attempt to assign negative values for the anthology's price and number of copies, we'll assign them as 0.0 and 0.
Album form:
public grade Album { individual String proper name; private String artist; private double toll; individual int numberOfCopies; public void sellCopies(){ if(numberOfCopies > 0){ numberOfCopies--; System.out.println("One album has sold!"); } else{ System.out.println("No more albums available!"); } } public void orderCopies(int num){ numberOfCopies += num; } public String getName() { render name; } public void setName(Cord proper noun) { this.proper name = name; } public Cord getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } public double getPrice() { return price; } public void setPrice(double price) { if(toll > 0) { this.price = toll; } else { this.toll = 0.0; } } public int getNumberOfCopies() { render numberOfCopies; } public void setNumberOfCopies(int numberOfCopies) { if(numberOfCopies > 0) { this.numberOfCopies = numberOfCopies; } else { this.numberOfCopies = 0; } } } StockKeeper grade:
public class StockKeeper { private Cord name; StockKeeper(String name){ setName(name); } public void manageAlbum(Anthology anthology, Cord proper name, String artist, double price, int numberOfCopies){ /* Defining states and behaviors for anthology */ album.setName(name); album.setArtist(creative person); album.setPrice(toll); album.setNumberOfCopies(numberOfCopies); /* Press album details */ System.out.println("Anthology managed by :"+ getName()); Arrangement.out.println("Album details::::::::::"); Arrangement.out.println("Album name : " + anthology.getName()); Organisation.out.println("Album artist : " + album.getArtist()); Organisation.out.println("Anthology price : " + anthology.getPrice()); System.out.println("Album number of copies : " + album.getNumberOfCopies()); } public String getName() { return proper noun; } public void setName(Cord proper name) { this.name = name; } } Main form:
public form Main { public static void main(Cord[] args) { StockKeeper johnDoe = new StockKeeper("John Doe"); /* Stock keeper creates album and assigns negative values for price and number of copies available */ johnDoe.manageAlbum(new Album(), "Glace When Moisture", "Bon Jovi", -1000.00, -50); } } Output:
Anthology managed by :John Doe Album details:::::::::: Album name : Slippery When Wet Album artist : Bon Jovi Album price : 0.0 Album number of copies : 0 With encapsulation, we've blocked our stock keeper from assigning negative values, significant we have control over the information.
Advantages of encapsulation in Java
- Nosotros tin can make a class read-only or write-only: for a read-only course, nosotros should provide only a getter method. For a write-only class, nosotros should provide merely a setter method.
- Control over the data: we tin control the data by providing logic to setter methods, just like we restricted the stock keeper from assigning negative values in the higher up example.
- Data hiding: other classes can't access private members of a course directly.
Inheritance
Let's say that the record store nosotros discussed higher up also sells Blu-ray movies.
As you can come across in the to a higher place diagram, in that location are many mutual states and behaviors (common code) betwixt Album and Movie.
When implementing this course diagram into lawmaking, are you going to write (or copy & paste) the unabridged code for Moving picture? If yous practice, you are repeating yourself. How tin can you avert code duplication?
This is where we use inheritance.
Inheritance is a machinery in which i object acquires all the states and behaviors of a parent object.
Inheritance uses a parent-child human relationship (IS-A relationship).
And then what exactly is inherited?
Visibility/access modifiers bear on what gets inherited from 1 class to another.
In Coffee, as a rule of thumb we make instance variables private and case methods public .
In this instance, we can safely say that the following are inherited:
- public instance methods.
- private instance variables (individual case variables can be accessed only through public getter and setter methods).
Types of Inheritance in Java
There are five types of inheritance in Java. They are unmarried, multilevel, hierarchical, multiple, and hybrid.
Class allows single, multilevel and hierarchical inheritances. Interface allows multiple and hybrid inheritances.
A course tin extend but 1 class however information technology tin can implement whatsoever number of interfaces. An interface can extend more than one interfaces.
Relationships
I. IS-A human relationship
An IS-A relationship refers to inheritance or implementation.
a. Generalization
Generalization uses an IS-A human relationship from a specialization course to generalization class.
Ii. HAS-A relationship
An instance of 1 class HAS-A reference to an instance of another class.
a. Aggregation
In this human relationship, the being of class A and B are non dependent on each other.
For this assemblage part, we going to see an case of the Educatee class and the ContactInfo class.
class ContactInfo { private Cord homeAddress; private String emailAddress; private int telephoneNumber; //12025550156 } public class Pupil { private String name; private int age; private int grade; private ContactInfo contactInfo;//Pupil HAS-A ContactInfo public void study() { System.out.println("Study"); } }
Student HAS-A ContactInfo. ContactInfo can be used in other places – for example, a company'due south Employee class can also utilize this ContactInfo form. Then Student can exist without ContactInfo and ContactInfo can exist without Student . This type of relationship is known as assemblage.
b. Composition
In this relationship, course B tin not exist without grade A – but class A can be without class B.
To give you lot an idea about composition, let's encounter an case of the Student class and the StudentId course.
grade StudentId { private String idNumber;//A-123456789 private Cord bloodGroup; private String accountNumber; } public form Student { private String proper noun; private int age; private int grade; individual StudentId studentId;//Student HAS-A StudentId public void written report() { System.out.println("Report"); } }
Student HAS-A StudentId. Student tin exist without StudentId only StudentId can not exist without Student. This type of relationship is known as composition.
Now, let's back to our previous record shop case that nosotros discussed in a higher place.
We can implement this diagram in Coffee to avert code duplication.
Advantages of inheritance
- Code reuse: the child class inherits all instance members of the parent class.
- You take more flexibility to alter lawmaking: changing lawmaking in place is enough.
- You can utilize polymorphism: method overriding requires IS-A human relationship.
Abstraction
Abstraction is a process of hiding the implementation details and showing only functionality to the user.
A common example of brainchild is that pressing the accelerator will increase the speed of a car. Just the driver doesn't know how pressing the accelerator increases the speed – they don't have to know that.
Technically abstract ways something incomplete or to be completed later.
In Coffee, nosotros tin achieve brainchild in ii ways: abstract class (0 to 100%) and interface (100%).
The keyword abstruse tin can be applied to classes and methods. abstruse and last or static tin can never exist together.
I. Abstruse class
An abstract class is one that contains the keyword abstract.
Abstruse classes can't be instantiated (can't create objects of abstract classes). They can take constructors, static methods, and terminal methods.
Ii. Abstract methods
An abstract method is one that contains the keyword abstruse.
An abstract method doesn't accept implementation (no method body and ends up with a semi colon). Information technology shouldn't be marked as private.
III. Abstract grade and Abstract methods
- If at to the lowest degree one abstract method exists inside a course then the whole course should be abstract.
- We can accept an abstract grade with no abstract methods.
- We can accept any number of abstract as well as non-abstract methods within an abstract form at the aforementioned fourth dimension.
- The first concrete sub form of an abstract course must provide implementation to all abstruse methods.
- If this doesn't happen, then the sub course besides should be marked as abstruse.
In a real world scenario, the implementation will exist provided by someone who is unknown to end users. Users don't know the implementation form and the bodily implementation.
Permit's consider an example of abstract concept usage.
abstract form Shape { public abstract void draw(); } course Circumvolve extends Shape{ public void draw() { System.out.println("Circle!"); } } public class Test { public static void main(String[] args) { Shape circle = new Circle(); circle.draw(); } }
When practise we want to mark a class as abstract?
- To force sub classes to implement abstruse methods.
- To stop having actual objects of that grade.
- To keep having a grade reference.
- To retain common class code.
Interface
An interface is a blueprint of a grade.
An interface is 100% abstract. No constructors are allowed here. Information technology represents an IS-A human relationship.
Note: Interfaces only define required methods. We can not retain common lawmaking.
An interface can have only abstruse methods, not concrete methods. Past default, interface methods are public and abstract. And so inside the interface, nosotros don't need to specify public and abstract.
So when a class implements an interface's method without specifying the access level of that method, the compiler will throw an error stating "Cannot reduce the visibility of the inherited method from interface". So that implemented method's admission level must be set to public.
By default, interface variables are public, static and final.
For instance:
interface Runnable { int a = 10; //like to: public static final int a = x; void run(); //similar to: public abstract void run(); } public class InterfaceChecker implements Runnable{ public static void primary(String[] args) { Runnable.a = 5;//The final field Runnable.a cannot exist assigned. } } Let's meet an example that explains the interface concept:
interface Drawable { void describe(); } class Circle implements Drawable{ public void draw() { System.out.println("Circle!"); } } public form InterfaceChecker { public static void main(String[] args) { Drawable circumvolve = new Circle(); circle.describe(); } }
Default and Static methods in Interfaces
Unremarkably we implement interface methods in a separate class. Let's say we are required to add a new method in an interface. And then we must implement that method in that separate class, too.
To overcome this issue Java viii introduced default and static methods that implement methods inside an interface, unlike abstract methods.
- Default method
public interface DefaultInterface { void slumber(); default void run() { System.out.println("I'm running!"); } } public course InterfaceCheckers implements DefaultInterface{ public void sleep() { System.out.println("Sleeping..."); } public static void main(String[] args) { InterfaceCheckers checker = new InterfaceCheckers(); checker.run(); checker.sleep(); } } /* Output: I'yard running! Sleeping... */ - Static method
Similar to static methods of classes, we can call them by their interface'southward name.
public interface DefaultInterface { void sleep(); static void run() { System.out.println("I'm running!"); } } public class InterfaceCheckers implements DefaultInterface{ public void sleep() { System.out.println("Sleeping..."); } public static void main(Cord[] args) { InterfaceCheckers checker = new InterfaceCheckers(); DefaultInterface.run(); checker.sleep(); } } /* Output: I'm running! Sleeping... */ - Marker interface
It'southward an empty interface. For instance, Serializable, Cloneable, and Remote interfaces.
public interface Serializable { //No fields or methods } Advantages of interfaces
- They help us employ multiple inheritance in Java.
- They provide abstraction.
- They provide loose coupling: objects are independent from one another.
When do we desire to change a course to an interface?
- To forcefulness sub classes to implement abstruse methods.
- To stop having actual objects of that grade.
- To keep having a class reference.
Annotation: Remember, nosotros can't retain common lawmaking inside the interface.
If yous want to define potentially required methods and common code, use an abstract form.
If you merely desire to define a required method, use an interface.
Polymorphism
Polymorphism is the power of an object to have on many forms.
Polymorphism in OOP occurs when a super class references a sub form object.
All Coffee objects are considered to be polymorphic as they share more than than one IS-A human relationship (at least all objects will pass the IS-A exam for their ain type and for the form Object).
Nosotros tin admission an object through a reference variable. A reference variable can exist of but one blazon. Once declared, the type of a reference variable cannot be inverse.
A reference variable can be declared as a class or interface type.
A unmarried object tin can exist referred to by reference variables of many unlike types as long every bit they are the same type or a super type of the object.
Method overloading
If a class has multiple methods that have same name but different parameters, this is known as method overloading.
Method overloading rules:
- Must have a different parameter list.
- May have different render types.
- May accept different access modifiers.
- May throw different exceptions.
class JavaProgrammer{ public void lawmaking() { Organisation.out.println("Coding in C++"); } public void code(Cord language) { Organisation.out.println("Coding in "+language); } } public grade MethodOverloader { public static void main(String[] args) { JavaProgrammer gosling = new JavaProgrammer(); gosling.code(); gosling.code("Java"); } } /* Output: Coding in C++ Coding in Java */ NOTE: Static methods can also be overloaded.
course Improver { public static int add(int a,int b) { return a+b; } public static int add together(int a,int b,int c) { return a+b+c; } } public class PolyTest { public static void main(String[] args) { Arrangement.out.println(Addition.add(5, 5)); System.out.println(Addition.add together(2, 4, half dozen)); } } Notation: We can overload the main() method but the Java Virtual Machine (JVM) calls the main() method that receives String arrays as arguments.
public class PolyTest { public static void main() { System.out.println("primary()"); } public static void main(String args) { Organisation.out.println("String args"); } public static void main(String[] args) { System.out.println("String[] args"); } } //Output: String[] args Rules to follow for polymorphism
Compile fourth dimension rules
- Compiler simply knows reference blazon.
- It can just look in reference type for methods.
- Outputs a method signature.
Run fourth dimension rules
- At runtime, JVM follows exact runtime blazon (object type) to observe method.
- Must lucifer compile time method signature to method in actual object'southward class.
Method overriding
If a subclass has the same method every bit alleged in the super form, this is known as method overriding.
Method overriding rules:
- Must have the same parameter list.
- Must have the aforementioned return type: although a covariant return allows us to change the return type of the overridden method.
- Must non take a more restrictive admission modifier: may have a less restrictive access modifier.
- Must not throw new or broader checked exceptions: may throw narrower checked exceptions and may throw any unchecked exception.
- Only inherited methods may be overridden (must take IS-A relationship).
Instance for method overriding:
public form Programmer { public void lawmaking() { System.out.println("Coding in C++"); } } public class JavaProgrammer extends Programmer{ public void code() { Arrangement.out.println("Coding in Java"); } } public course MethodOverridder { public static void main(String[] args) { Programmer ben = new JavaProgrammer(); ben.code(); } } /* Output: Coding in Java */ Notation: Static methods tin can't be overridden because methods are overridden at run time. Static methods are associated with classes while instance methods are associated with objects. So in Java, the main() method also can't exist overridden.
Notation: Constructors tin can exist overloaded but non overridden.
Object types and reference types
form Person{ void eat() { System.out.println("Person is eating"); } } grade Pupil extends Person{ void study() { System.out.println("Student is studying"); } } public course InheritanceChecker { public static void main(String[] args) { Person alex = new Person();//New Person "is a" Person alex.eat(); Student jane = new Educatee();//New Student "is a" Student jane.swallow(); jane.report(); Person mary = new Student();//New Student "is a" Person mary.eat(); //Educatee chris = new Person(); //New Person isn't a Student. } } In Person mary = new Student(); , this object creation is perfectly fine.
mary is a Person blazon reference variable and new Student() will create a new Pupil object.
mary can't access report() in compile time because the compiler only knows the reference blazon. Since there is no report() in the reference type class, it can't access it. But in runtime mary is going to exist the Educatee type (Runtime type/ object type).
Please review this post for more information on runtime types.
In this instance, we can convince the compiler by saying "at runtime, mary will exist Student type, so please allow me to phone call it". How can we convince the compiler like this? This is where we use casting.
We can make mary a Pupil type in compile fourth dimension and tin can call study() by casting information technology.
((Student)mary).study(); We'll learn about casting next.
Object type casting
Java blazon casting is classified into two types:
- Widening casting (implicit): automated type conversion.
- Narrowing casting (explicit): need explicit conversion.
In primitives, long is a larger blazon than int . Similar in objects, the parent class is a larger type than the child course.
The reference variable only refers to an object. Casting a reference variable doesn't change the object on the heap merely it labels the same object in another mode by means of example members accessibility.
I. Widening casting
Superclass superRef = new Subclass(); Two. Narrowing casting
Subclass ref = (Bracket) superRef; Nosotros have to be careful when narrowing. When narrowing, we convince the compiler to compile without any fault. If we convince it wrongly, we will become a run time error (usually ClassCastException).
In order to perform narrowing correctly, we employ the instanceof operator. Information technology checks for an IS-A human relationship.
class A { public void display(){ Arrangement.out.println("Grade A"); } } form B extends A{ public void display(){ System.out.println("Grade B"); } } public class Examination { public static void chief(String[] args) { A objA = new B(); if(objA instanceof B){ ((B)objA).display(); } } } /** * Output: Class B */ As I already stated before, we must call up one important thing when creating an object using the new keyword: the reference type should exist the aforementioned type or a super type of the object type.
Conclusion
Thank you everyone for reading. I promise this commodity helped yous.
I strongly encourage you to read more related articles on OOP.
Checkout my original article series on Medium: Object-oriented programming principles in Java
Please feel free to allow me know if you accept any questions.
Dream is not that which you run into while sleeping it is something that does not let you sleep.
― A P J Abdul Kalam, Wings of Fire: An Autobiography
Thank you.
Happy Coding!
Acquire to code for free. freeCodeCamp'southward open source curriculum has helped more than 40,000 people go jobs as developers. Go started
Source: https://www.freecodecamp.org/news/java-object-oriented-programming-system-principles-oops-concepts-for-beginners/
0 Response to "Oops Try Again Did You Call the Namestring Function"
ارسال یک نظر