Skip to main content

Java Keywords (Part XXIV): native

Java keyword list abstract continue for new switch assert default goto * package synchronized boolean do if private this break double implements protected throw byte else import public throws case enum instanceof return transient catch extends int short try char final interface static void class finally long strictfp volatile const * float native super while Keyword marked with an asterisk (*) are keywords that, although valid, are not used by programmers. This is the last chapter of the Java Keyword series. This is probably the keyword I have used the least. In my 20 year career as a software developer, I have used this keyword once, and that was to make some addition to legacy code. The keyword native is a method modifier . Basically, it is a keyword that can only be applied to methods. According to the Java Language Specification (JLS), A method that is native is implemented i...

Java Keywords (Part V): Classes vs Interfaces

This is not a break in my Java Keyword series. This is a continuation of the series that focuses in two things. The primary goal is to explain what an interface is (which differentiates them from classes) and go over a few examples that illustrate why interfaces are not just needed, but essential for robust and reusable software solutions.

Because of new improvements introduced with Java 8, I will also introduced the concept of default methods; although will do so in a separate article... A second part to this one. I feel doing that is necessary for keeping the scope of this article as narrow as possible for the sake of simplicity and clarity. Interestingly enough, how to use interfaces will also be covered in a separate article where I will be discussing the Object-Oriented concept of inheritance. In the new article, I will be emphasizing in the keywords extends, implements, and super.

The Java keyword list has 18 keywords grayed out. This article will only cover the interface keyword. That puts us at 38% of keywords covered by these series of articles. Amazingly, that's almost sufficient to built simple applications. I suggest that if have not read any of the articles in Java Keyword series, you read them before proceeding further. Also, go back and read the one about Data Types. All of these articles are from September 2018. That should help you find them quickly.

Java keyword list

abstract continue for new switch
assert default goto* package synchronized
boolean do if private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp volatile
const* float native super while
Keyword marked with an asterisk (*) are keywords that, although valid, are not used by programmers.

Although the list above is arranged in alphabetical order, I will go through them in a different order.

What is an interface?

An interface is an abstract data type that is used to specify a behavior that classes must implement. Before delving into what this means, let us examine the most basic form of an interface in Java.


public interface Pet
{
    // internal details omitted (for the moment)
}
Just like classes, in Java, interfaces are declared using a specific keyword. In this case, the interface keyword is used as we can see from the example above. So, classes are declared using the class keyword and interfaces are declared using the interface keyword. Easy enough. However, there are a few other characteristics you have to be aware of. If you remember from Java Keywords (Part II) article, I discussed the concept of an abstract class. What I didn't mention at the time (and didn't mention in the Classes and Objects article), is that abstract classes CANNOT be instantiated at all... not with the new operator, and not with any other object construction mechanism. If you really think about this, it makes perfect sense. Something "abstract" cannot be easily defined. Something "abstract" is just a concept, not a thing and objects are specific things.

The interface I defined above is called "Pet." We can all agree that some animals can be pets. For the sake of simplicity, let's not get into the concept of breeds. Now, we can also agree that (for example) not all dogs are pets; for one reason or another. Since, by definition, an interface is used to specify behavior, we can use the concept of interfaces to "inject" certain behavior characteristics of pets that are not exhibited in other types of animals. This is all so confusing....


public class Dog
{
    // Details omitted
}

public class Cat
{
    // Details omitted
}

public interface Pet
{
    void learnTrick(String trickName);
    void doTrick(String trickName);
    void giveName(String name);
    void respondByName(String trickName);
    void dressUp();
}

The Pet interface illustrated above contain 4 abstract methods. However, differently than abstract classes, with interface the use of abstract keyword is not necessary when declaring abstract methods. Why? Because interfaces can only contain two types of methods: abstract methods (shown above) and default methods (covered in another article). I will also go in more detail regarding the use of access modifiers with interface methods at a later time. Additionally, methods in an interface are inherently public. Therefore, omitting the use of the keyword public does not make the methods package-private (or default access) as you learned in Part I of this series. This is only true of interface methods. Lastly, interfaces are incapable of containing variables like classes do. Only constants can be declared in interfaces and even this is currently considered bad practice.

In my example, I simply want to illustrate that there is a difference between animals (in this case dogs) that are not pets and those that are. For example, we often teach our pets tricks so that they could do those tricks later on for our amusement. We also give our pets names and they respond when we call them by that name. In contrast, a dog that has never been a pet, like a stray dog, does not know any tricks and do not come to us when we call them. But, being a pet is not something exclusive to dogs. Cats can also be pets too. And these pet cats can learn tricks, do tricks, be given a name, respond by its name, and be dressed up.


Pet myPet = new Dog();
Pet yourPet = new Cat();

In case I didn't mention this before, when creating object references, the portion to the left of the equals sign is used to declare the object's Type. The portion of the right of the equals sign defines the object being created. In order for this to be possible, the two must be compatible. This means that objects of type "Dog" must also be of type "Pet." The same goes for "Cat" objects. Why is this important? How will this help me create robust and reusable software solutions? I admit that this example is very trivial. But, I am glad you asked...

Suppose you have a requirement that you must maintain a list of names. In Java, you can use the class java.util.ArrayList which lists items in the order they are inserted and accept duplicate entries. Assuming that two people with the same name exist, the following is correct:


ArrayList myList = new ArrayList();
myList.add("John");
myList.add("Mary");
myList.add("Hector");
myList.add("John");

The above list contains four names: Hector, Mary, and John twice. Later on, this requirement changes and now your list must be sorted alphabetically AND cannot accept any duplicates. If this happens, your code will break because it depends EXCLUSIVELY on how a java.util.ArrayList behaves. For this reason, Java created another class called java.util.TreeSet that behaves differently. Now, in case you are wondering "what does that have to do with this example?", the answer is simple: Both classes implement the java.util.Collection interface. One of the methods in this interface is the add method.


Collection myList = new ArrayList();
myList.add("John");
myList.add("Mary");
myList.add("Hector");
myList.add("John");

Replacing ArrayList on the right of the equals sign with Collection allows me to refer to myList as a generic collection and not a strict ArrayList.


Collection myList = new TreeSet();
myList.add("John");
myList.add("Mary");
myList.add("Hector"); // Will be inserted before John
myList.add("John"); // Will not be inserted because it is a duplicate entry

Replacing ArrayList on the left of the equals sign with TreeSet allows me to change the behavior of myList without breaking the code that inserts values into the collection. The end result of this code is that, the ArrayList will have four elements shown in the order they were inserted, whereas the TreeSet collection will have three elements sorted in natural order (alphabetically in this case).

Summary

Interfaces makes it possible to inject behaviors that are exclusive to certain members of a given category and allows us to refer to objects by this generic type. The end result, as shown in the array list and tree set example is that we are able to change the implementation of a concrete class without affecting the code; thus allowing us to make a type replacement without modifying existing code. This means I can refer to array lists and tree sets as simple "collections" and the supporting code will work according to the specific implementation of this collection without breaking the code. Therefore, when going the opposite way, from "collection" to array list or tree set, the "myCollection" will behave as the specific type of "collection."

Next up, Part VI: If/Else Flow-Control Statements

Comments

  1. All I gather is that inheritance allow child class to define methods and functions within their boundaries, which doesn't affect the codes from the parent nor others child classes. Which is useful especially if the parent class is more general that it need multiple child classes.

    ReplyDelete
    Replies
    1. That is true. But there is much more to inheritance. Inheritance could also have adverse effects. One of such effects is the forcing changes down the hierarchy. For example, if you have to add an additional argument to a protected method, ALL of the sub-classes are adversely impacted. For this reason, composition is preferred over inheritance.

      https://professorfontanez.blogspot.com/2016/02/aggregation-and-composition.html

      With inheritance, the key question that should be answered is the following "is the subclass a type of the super class?" If the answer is yes, then it make sense to use inheritance. HOWEVER, I would try to implement an interface before inheriting from a super class. Also, avoid deep inheritance trees. Some people say it should never be more than 3 to 4 levels deep. And remember, the top level of all classes is Object.

      Delete

Post a Comment

Popular posts from this blog

Implementing Interfaces with Java Records

If you have not read my article on Java records and do not know about this topic, please read my blog titled " Customizing Java Records " first and then come back to this one. Now that you know how to customize Java records, implementing an interface using Java records should be very easy to understand. If you don't know about interfaces in Java, you can read more on my article about interfaces. The recipe for implementing an interface is simply an expansion of what you learned in my previous blog on how to customize a Java record. Following our Rectangle example, let's create an interface with the same two methods we used before. public interface Shape { double area(); double perimeter(); } Now, let's further customize the previous example by doing two things: Add implements Shape at the end of the record declaration (after the record constructor), and Add @Override to the existing methods to ensure these methods com...

Customizing Java Records

If you have not read my article on Java records and do not know about this topic, please read my blog titled " Java Keywords Addendum: The Java Record " first and then come back to this one. What is a customization of a record? A customization of a record is simply the addition of code inside the body of the class. Before proceeding further, let's recap important aspects of a Java Record: Java records are immutable Because of item 1 above, you cannot add new fields unless defined in the record constructor Java records already override: Object#equals(Object) and Object#hashCode() , and then override Object#toString() You could redefine overridden methods as part of your customization if you would like. For example, if you want a fancier implementation of the Object#toString() method, you could do so. Let's look at our first customization example. Using the example from my previous blog, public record Student(...

Object-Oriented Programming Basics: What is in a Class?

EDITORIAL NOTE : This article was published briefly back in 2016 and quickly set back to draft because I wasn't happy with its contents. It is a shame that it was taking me three years to revisit this topic and work on a new and improved version. At least, I'm hoping it will be to the liking you the reader. Keep in mind that the opening paragraph will still read as if I just wrote it for my (former) students at Texas Wesleyan. I started working on lecture on the topic of Object-Oriented (OO) Programming by gathering some material, old and new, when I realized this might be good and simple post for my second attempt at blogging. To be completely honest, in the 8 hours I spent collecting information and preparing material for this week's lecture, I realized I still made some of the mistakes I am about to blog about. I am actually hoping I can write a series of postings regarding Object-Oriented Programming (OOP). But to do so, I must start from the very beginning. ...