Extracting superclasses enables NetBeans to add different levels of hierarchy even after the code is written.
Usually, requirements changing in the middle of development, and rewriting classes to support inheritance would quite complicated and time-consuming.
NetBeans enables the developer to create those superclasses in a few clicks and, by understanding how this mechanism works, even creates superclasses that extend other superclasses.
We will need to create a Project based on the Getting Ready section of the previous recipe, since it is very similar.
The only change from the previous recipe is that this recipe's project name will be SuperClassExtraction.
After project creation:
Replace the entire content of the DataAnalyzer.java
with the following code:
package superclassextraction; import java.util.ArrayList; public class DataAnalyzer { ArrayList<String> data; static final boolean CORRECT = true; static final boolean INCORRECT = false; private void fetchData() { //code } void saveData() { } public boolean parseData() { return CORRECT; } public String analyzeData(ArrayList<String> data, int offset) { //code return ""; } }
Now let's extract our superclass.
DataAnalyzer.java
class, select Refactor and Extract Superclass....When the Refactor button is pressed, NetBeans copies the marked methods from DataAnalyzer.java
and re-creates them in the superclass.
NetBeans deals intelligently with methods marked as abstract. The abstract methods are moved up in the hierarchy and the implementation is left in the concrete class. In our example analyzeData is moved to the abstract class but marked as abstract; the real implementation is then left in DataAnalyzer.
NetBeans also supports the moving of fields, in our case the CORRECT and INCORRECT fields.
The following is the code in DataAnalyzer.java:
public class DataAnalyzer extends Analyzer { public void saveData() { //code } public String analyzeData(ArrayList<String> data, int offset) { //code return ""; } }
The following is the code in Analyzer.java:
public abstract class Analyzer { static final boolean CORRECT = true; static final boolean INCORRECT = false; ArrayList<String> data; public Analyzer() { } public abstract String analyzeData(ArrayList<String> data, int offset); public void fetchData() { //code } public boolean parseData() { //code return DataAnalyzer.CORRECT; } Java refactoringJava refactoringsuperclasses, extracting}
Let's learn how to implement parent class methods.
Let's add a method to the parent class:
Analyzer.java
and enter the following code:public void clearData(){ data.clear(); }
DataAnalyzer.java
, press Alt+Insert and select Override Method.... DataAnalyzer.java:
@Override public void clearData() { super.clearData(); }
As with Extracting a superclass, NetBeans also enables the developer to create interfaces out of pre-existing concrete classes.
As with superclasses, it is also possible to create a more complex hierarchy when extending different interfaces and combining them together.
We will need to create a project based on the Getting Ready section of the previous recipe, since it is very similar.
The only change from the previous recipe is that this recipe's project name will be InterfaceExtraction.
Replace the entire content of DataAnalyzer.java
with the following code:
package interfaceextraction; import java.util.ArrayList; public class DataAnalyzer { ArrayList<String> data; static final boolean CORRECT = true; static final boolean INCORRECT = false; private void fetchData() { //code } void saveData() { } public boolean parseData() { return CORRECT; } public String analyzeData(ArrayList<String> data, int offset) { //code return ""; } }
Now let's extract our interface.
NetBeans copies the method declaration of selected methods contained in our concrete class and creates an interface with them.
Then our concrete class is marked with the implements keyword.
The interface is then placed in the same package as our concrete class.
package interfaceextraction; import java.util.ArrayList; public interface IDataAnalyzer { String analyzeData(ArrayList<String> data, int offset); boolean parseData(); }
Extracting interface from classes that already have an interface; undoing interface extraction; and understanding the options when refactoring.
Let's create another interface directly from the class that already implements an interface.
Change the access modifier of fetchData method from default to public:
public void saveData() { //code }
Perform the Extract Interface process one more time:
As seen in the previous screenshot another option is given to the developer, the implements IDataAnalzyer.
This option will replace the interface that the class is currently implementing with the newly generated one, and then extend that new interface with the original.
Here is some code to exemplify:
Our class:
public class DataAnalyzer implements IDataAnalyzerDB
Our new interface:
public interface IDataAnalyzerDB extends IDataAnalyzer
Don't worry, NetBeans is well-prepared for this situation.
Simply right-click DataAnalyzer.java
, and inside of the Refactor sub-menu there is the Undo [Extract Interface] option.
When clicking Preview in the Extracting Interface the developer is presented with the Refactoring Options.
In this window it is possible to go into great detail over what will get refactored during the above tasks.
In this dialog we can select any, all or none of the hierarchical options.
It is possible, for example, not to enable the creation of the interface, even though this would have the consequence of code not compiling, but this gives the developer the chance to make necessary changes to whatever is needed.
Encapsulation is one of the core principles of object-oriented programming and NetBeans goes to great lengths to simplify the process of generating the necessary code for it.
Creating the code to be encapsulated:
We will need to create a project based on the first Getting Ready section of this chapter, since it is very similar.
The only change from the previous recipe is that this recipe's project name will be EncapsulatingFieldsProject.
We will also need to add a Java class with Person as the class name with entities as the package name.
Replace the code within Person.java
with:
package entities; public class Person { long id; String firstName; String lastName; int age; String address; String email; }
And save the file.
With Person.java
open in the Java editor:
Person.java
.NetBeans does a great job when creating all the getters and setters with the default values, even letting the developer select each individual method for each property.
This gives a good balance of what should be made accessible and how it should be accessible.
By leaving all of the default options in the field, NetBeans marks all variables as private, adds get/set methods for each variable and documents them.
Here is a snippet of the generated code for the firstName property:
private String firstName; /** * @return the firstName */ public String getFirstName() { return firstName; } /** * @param firstName the firstName to set */ public void setFirstName(String firstName) { this.firstName = firstName; }
We will better understand the many options provided by the Encapsulate dialog in NetBeans by considering what follows.
The options presented by the Encapsulate Field dialog are very straightforward:
Javadoc option enforces the location where the Javadoc for the accessor methods will come from.
Be it by copying from the fields with the Copy from field option, letting the IDE do the hard work of creating the Javadoc for all of the methods with Create default comments, or simply None.
Field Visibility enables the developer to choose which Java access modifier should be applied to the variable declaration:
Accessor Visibility enables the developer to choose which Java access modifier should be applied to the accessor methods (get/set).
3.15.226.239