Design Hints for Inheritance in Java

Search for a command to run...

No comments yet. Be the first to comment.
1. Sạch Phải công nhận là Sing sạch, đi đâu cũng thấy có người đang quét dọn, tỉa cành, gom rác, cắt cỏ,… Chi phí để duy trì môi trường cảnh quan chắc cũng không hề nhỏ. 2. Giao thông công cộng Bên này chủ yếu đi bằng tàu điện (MRT) và xe bus, chi ph...
In the previous article, I covered the basic concepts and introduced a 5-step process for applying DDD in practice. Today, I will bring you a bigger challenge. In this article, we will work through an

I. Why DDD matters? A Bigger Picture Over the years, as business needs have grown increasingly complex, our application systems have evolved - from monoliths to SOA, and now to microservices. This evolution demands a rational approach to component de...

Behind every robust software system lies a suite of well-structured unit tests. But what defines a great unit test? In this article, we’ll examine its anatomy and best practices to ensure your tests are both reliable and effective. I. A Bigger Pictur...

This is a nice feedback from my Singaporean Scrum Master for 2024. According to Vietnamese beliefs, 2024 marked the final year of a challenging three-year period (Tam Tai) for those born in 1996, a time filled with uncertainties and difficulties. Al...
Some hints that we have found useful when using inheritance.
Instead of replicating each field in subclasses, we should put common fields and methods on the superclass.
Some programmers think it is a good idea to define most instance fields as protected, “just in case” so that subclasses can access these fields if they need to. However, the protected mechanism doesn’t give much protection, for two reasons:
Inheritance is a handy code-saver, but sometimes people overuse it. For example, suppose we need a Contractor class. Contractors have names and hire dates, but they do not have salaries. Instead, they are paid by the hour, and they do not stay around long enough to get a raise.
There is the temptation to form a subclass Contractor from Employee and add an hourlyWage field.
public class Employee {
private double salary;
private LocalDate hiredDate;
}
public class Contractor extends Employee {
private double hourlyWage;
. . .
}
Look good, right?
But this is not a good idea, because now each contractor object has both a salary and hourly wage field.
The contractor-employee relationship fails the “is–a” test. A contractor is not a special case of an employee.
If you find any method in superclass which is not appropriate or doesn't make sense in the subclass, inheritance is not appropriate.
The substitution principle applies not just to the syntax but, more importantly, to behavior. When you override a method, you should not unreasonably change its behavior. The compiler can’t help you - it cannot check whether your redefinitions make sense.
Technical debt and bugs come from here :)))
Whenever you find code of the form
if (x is of type 1)
action1(x);
else if (x is of type 2)
action2(x);
think about polymorphism.
Do action1 and action2 represent a common concept? If so, make the concept a method of a common superclass or interface of both types. Then, you can simply call:
x.action();
Code that uses polymorphic methods or interface implementations is much easier to maintain and extend than code using multiple type tests.
The reflection mechanism lets you write programs with amazing generality, by detecting fields and methods at runtime. This capability can be extremely useful for systems programming, but it is usually not appropriate in applications. Reflection is fragile—with it, the compiler cannot help you find programming errors. Any errors are found at runtime and result in exceptions.
(Source : Core Java Volumn I - Fundamentals)