Java - subclass validation design pattern - java

I am having a base class C with fields X, Y and Z.
C1 extends C and is having an extra field, T.
In the C1 constructor, I do call the super (C) constructor with some hard coded values for the fields X, Y and Z. Then I set T.
Are there any patterns to automatically validate all the fields of C1 by doing something in the C constructor ? So I am trying to push the automatic validation to the base class.
Please note that calling the super constructor should be done before any statement in the C1 constructor. I started with some abstract validate() method, but I am not I am on the right track.
Thanks.

As a matter of principle, C should not know about C1's properties, because C1 is a specialization of C. However, what you can do is make an abstract validate() method in C, that must be implemented by C1. Then, in C's constructor, you can call the abstract method. Since, C1 will have to implement the validate(), it can then add it's property/field validation there.

Although it is against all OO principles, you could take advantage of Java's reflection property. Via reflection you can find out which methods and fields a class has. So you could pass the subclass object to the base class and the base class could check for all fields and validate them. If you do this at the end of the subclass constructor, you could let the validation method return a value to see if the values are valid or not.
I want to state that I don't think it's the right way to go but it should work

I would say that the super class should validate itself. An object needs to enforce its own contract. Any validation of C's values should be done in its own constructor. Likewise, the subclass should validate itself.
public class A {
private int x;
public A(int x) {
if (x < 0) throw new IllegalArgumentException("x cannot be negative");
this.x = x;
}
}
public class B extends A {
private String y;
public B(int x, String y) {
super(x);
if (y == null) throw new IllegalArgumentException("y cannot be null");
this.y = y;
}
}

class C{
Object x, y, z;
public C(Object x, Object y, Object z){
this.x = x;
this.y = y;
this.z = z;
}
public boolean validate(){ /**do stuff**/}
}
class D{
public D(/**args**/){
super(/**args**/);
if(validate()){
/**do stuff**//
}
}
}

Related

Java wider object assignment conversion

In the following example, I don't understand why Base b1 = new Derived();
System.out.println(b1); prints out x=10, z=20. My understanding is that since b1 has a static type of Base, it don't have access to the fields in Derived, so z shouldn't haven been printed out. Can someone please help to explain? Many thanks!
class Base {
int x;
public Base1() { x = 10; }
public Base1(int x) { this.x =x; }
public String toString() {
return "x=" + x ;
}
}
class Derived1 extends Base1 {
int z = x * 2;
public Derived1() {}
public Derived1(int x, int z) {
super(x);
this.z = this.z + z;
}
public String toString() {
return "x=" + x + ", z=" + z;
}
}
The object is a Derived, not a Base. Your interface to the object from b1 is Base. Base has toString, so you can access toString. The implementation you access is the one the object has, which is provided by Derived, which uses z. The implementation of Derived#toString can access z because its reference to the object is via a Derived reference (this), not a Base reference.
As Oli points out in a comment, this is fundamental to polymorphism — having the behavior of the object depend on the object rather than the interface to the object.
If the internals of the object were dictated by the interface we had to it, we'd be in a fair bit of trouble trying to implement interfaces! :-)
Straight from http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
A subclass inherits all of the public and protected members of its
parent, no matter what package the subclass is in. If the subclass is
in the same package as its parent, it also inherits the
package-private members of the parent. You can use the inherited
members as is, replace them, hide them, or supplement them with new
members
In your code you call the default constructor to create a new Derived1 object : Base b1 = new Derived();and this in turn calls the default constructor of the parent class where there you happen to set x = 10. After that, you go to this line int z = x * 2;

Accessing a private variable through static method in java

Let say I have the following java classes:
Class A:
public class A {
private int x;
public A(int x){
this.x = x;
}
public static void main(String[] args) {
A a = new A(1);
B b = new B(1,2);
System.out.println((A)b.x);
}
}
Class B:
public class B extends A {
public int y;
public B(int x, int y){
super(x);
this.y = y;
}
}
Why does the compiler marks the access to x on this line
System.out.println((A)b.x);
as an error, even though I'm trying to access x from the class in which it is defined?
Is it because of:
1. the use of polymorphism?
2. the use of a static method?
3. the use of the main method?
You need to make it ((A)b).x to properly type cast it
Note : You are trying to type cast the property x to type A. That's the error!
int x is private therefore it can't be reached from outside of the scope of the class. You could mark it as protected. This way it will still have limited scope. Classes that extend A will be able to access the variable freely.
This is because the dot operator has precedence over the cast operator. This will work, because it forces the cast operator to be applied before the dot operator:
System.out.println(((A)b).x);
Demo on ideone.
When you write (A)b.x, the compiler try to cast b.x into A, but x is an int
Moreover, you don't need to cast b into A and you can't access b.x because x is a private field.
You may need a getter for this, like b.getX()
You have follwing issues
Compiler will show "Field not visible" Error,Because you trying to access private method of parent class
Syntactically. operator has precedence over cast operator
And another impotent thing is that No need to cast a child object to parent to access parent specific members, Because they are already inherited to the child, Here the member you are accessing is private ,which is not inherited. Even if you cast to parent you cant access private members using child object.
Because you are trying to cast an int into A. You need to wrap the cast around the object and then call .x.
Your call is equivalent to (A)(b.x), when it should be ((A)b).x.
public static void main(String[] args) {
A a = new A(1);
B b = new B(1,2);
System.out.println(((A)b).x);
}
Basically, two issues exist here.
One being that int x is private so it cannot be accessed from the sub-class.
Now even if you change the access criteria of int x to publicor protected; the code will still not work because (A)b.x will try to typecast an integer (read x) to an object (read A). Instead of this, you should use ((A)b).x

Which of the following methods will be legal in the subclass?

I am confused about how to create methods in a subclass. I am hitting my head against a brick wall with this and not even sure how to word the question.
import java.io.*;
public class A {
public double method1(double x, double y) { return 1.0; }
}
class B extends A {
//subclass method to be placed after this line
}
public double method1(double x, double y) { ... }
public int method1(double x, double y) { ... }
public double method1(int x, int y) { .... }
public int method1(double x, double y, double z) { ... }
Which of the following methods will be legal in the subclass and why?
Overrides method1 with new functionality.
Illegal because it has the same parameter signature but a different return type.
3,4. legal but are really separate methods.
Just consider the argument types to be part of the method name:
Only if the name plus the argument types fully match, you override the same method with new functionality. In this case, the return type must match (starting with Java 1.5, the return type may be specialized in subclasses, see https://blogs.oracle.com/sundararajan/entry/covariant_return_types_in_java)
In other cases, the added methods are just separate methods with the same name. Java statically picks the right one for each invocation at compile time based on the provided argument types. If arguments are compatible and the names are the same for multiple methods, it picks the closest match.
If you put the following methods in class, as per my understanding, this should happen:
public double method1(double x, double y) { ... }
This is overridden method, which means you overriding the behavior of method1 in your subclass, which is perfectly legal.
public int method1(double x, double y) { ... }
Compilation error: This is a try to do method overloading but not in a legal way. Method overloading allows to have same method name but different type/number of arguments. Method overloading is done with different parameter list but NOT by using a different return type.
public double method1(int x, int y) { .... }
This one is a legal overloaded method
public int method1(double x, double y, double z) { ... }
Again a legal overloaded method
Overrides the method in A and is legal
Is illegal because returntype is different and not a specialisation of the returntype of the method in A
Is an overloaded method because the argument types are different
Is an overloaded method because there are more parameters
See also http://en.wikipedia.org/wiki/Function_overloading and http://en.wikipedia.org/wiki/Method_overriding
Legal overriding
Not Legal overriding because return type should be covarient or same
legal overloading
legal overloading
overriding rules :- * parameter must same
return type must same or it should be covarient
exception if it is checked it should be sub class of that overridden method
access modifier should be same or less restricted
overloading rules :- * parameter must different
return type can be same
access modifier can be same
Read Katherine Sierra, Bert Bates (SCJP Book) for full rules or Java doc

what is the purpose of this(1) & this(2) in the following program?

in the following program i have use the this(1) & this(2) what is the purpose of using this(1) & this(2) and i also want to know is this is a keyword or method?I am new to java programming language.
class Const
{
Const()
{
this(1);
System.out.println(1);
}
Const(int x)
{
System.out.println(2);
}
}
class const1 extends Const
{
int a;
const1()
{
this(8);
System.out.println(3);
}
const1(int x)
{
System.out.println(4);
}
public static void main(String s[])
{
new const1();
}
}
These are alternate constructor invocations. They invoke another constructor in the same class. This allows multiple constructors to share the same code for common behavior. Without it, you'd sometimes be forced to repeat yourself.
For example:
Const()
{
this(1);
...
}
Calls this constructor with the actual argument "1":
Const(int x) { ... }
You can use the keyword super() in a similar way to invoke a superclass constructor.
From the Java Language Specification, 8.8.7.1, Explicit constructor invocations:
Explicit constructor invocation statements can be divided into two kinds:
Alternate constructor invocations begin with the keyword this (possibly prefaced with explicit type arguments). They are used to invoke an alternate constructor of the same class.
Superclass constructor invocations begin with either the keyword super (possibly prefaced with explicit type arguments) or a Primary expression. They are used to invoke a constructor of the direct superclass.
this() if used inside a constructor is actually used to invoke another constructor of the same class. It is particularly useful if you keep overloaded constructors .
public class Rectangle {
private int x, y;
private int width, height;
public Rectangle() {
this(0, 0, 0, 0);
}
public Rectangle(int width, int height) {
this(0, 0, width, height);
}
public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
...
}
Remember, this() or super() has to be the first statement in the constructor , if you use them . Hence they cannot be used together inside a constructor.
this if used inside a method body will refer to the current instance on which the method was invoked.
Read the Oracle tutorial for this and super.
Its similar to creating overloads to methods so they emulate having 'optional' parameters such as this:
DoStuff(int x, int y)
{
//Stuff
}
DoStuff(int x)
{
DoStuff(x, x);
}
Except you are doing it in the constructor (if they don't pass a value just use the value 1). To answer the question this invokes the constructor of the object.

Inheritance and methods

I'm having a problem with the constructors of classes and sub-classes(that extend the first class)
This is the basic class's constructor:
public Airplane(int x, int y, int width)
{
this.x = x;
this.y = y;
this.width = width;
createSeats();
}
And here is another class's constructor that extends the basic class
public Boeing(int x, int y, int width)
{
super(x,y,width);
createSeats();
}
The problem is that createSeats() is another method in both classes, but Boeing has to override the main one. How can I make it so that this will work without taking the createSeats() method out?
If you know you want all subclasses of Airplane to call createSeats() on construction then you can leave the call in the Airplane constructor and remove from Boeing.
If you only want particular subclasses, e.g. Boeing to call createSeats() on construction then you can leave the call in the Boeing constructor and remove from Airplane.
You don't need the invocations in both constructors, leaving them there will result in createSeats() being called twice for each Boeing you initialise.
The call to the super constructor already includes the call to the createSeats() method, so you don't have to reinclude it in the Boeing constructor.
If you only want to change the behavior of creating seats, just override that method.
class Airplane {
public Airplane(int x, int y, int width)
{
this.x = x;
this.y = y;
this.width = width;
createSeats();
}
void createSeats() { /* create them */ }
}
class Boeing {
public Boeing(int x, int y, int width)
{
super(x,y,width); // same steps as super class
}
#Override
void createSeats()
{
// do something else entirely
// possibly call super.createSeats()
}
}
Frequently a default implementation of a method is provided in a super class, which allows you to customize the behavior in a subclass by overriding the method in a subclass. E.g. Does an Airplane know how to create seats on a Boeing? Probably not, therefore you would override the createSeats() in your subclass to provide the specific implementation that works for you particular type of Airplane.
The fact that the createSeats() method is called from inside your super class' constructor guarantees that the method in question will always be called on construction of the object. This is a common design pattern. It's called template method. Basically you have a method that encapsulates the execution of a number of methods in a certain order to produce an outcome. In your case there's one method namely createSeats().
I agree with #milkplusvellocet's answer, however you also said "The problem is that createSeats() is another method in both classes, but Boeing has to override the main one." If you ever need to call a superclass's method instead of your own, you can always call super.createSeats(). That way you can always differentiate between methods in the superclass and your own methods.
However, that said, that's almost always used in the method you're overriding. For example,
#Override
public void createSeats() {
doSomethingSpecial();
super.createSeats();
}
#Override
before the method you want to override should do the job

Categories

Resources