I wrote the below code, and as you see, in the constructor I call some methods to perform certain operations. And now what I am inquiring about is, whether it is a good practice to call those methods from the constructor OR declare those methods as public and instantiate an object from the class info, and let the object call those methods? What is the good practice for that?
Code:
class Info {
public RoadInfo(String cityName, double lat, double lng) throws FileNotFoundException, SAXException, IOException, XPathExpressionException {
// TODO Auto-generated constructor stub
this.cityname = cityName;
this.lat = lat;
this.lng = lng;
this.path = "c:"+File.separatorChar+this.cityname+".xml";
System.out.println(path);
this.initXPath();
this.method1()
this.method2()
..
this.expr = "//node[#lat='"+this.lat+"'"+"]/following-sibling::tag[1]/#v";
this.xPath.compile(this.expr);
String s = (String) this.xPath.evaluate(this.expr, this.document, XPathConstants.STRING);
System.out.println(s);
}
TLDR In my opinion, using methods inside of a constructor is a sign of bad design. If you aren't looking for design advice, then the answer "no there's nothing wrong with it, technically speaking, as long as you avoid calling non-final methods" should do you fine. If you ARE looking for design advice, see below.
I think your example code is not good practice at all. In my opinion, a constructor should only receive values which is relevant to it and should not need to perform any other initialization on those values. There's no way for you to test that your constructor 'works' with all of those little extra steps - all you can do is construct the object and hope that everything ends up in the correct state. Further, your constructor ends up with more than one reason to change, which violates the SRP.
class Info {
public RoadInfo(String cityName, double lat, double lng) throws FileNotFoundException, SAXException, IOException, XPathExpressionException {
// TODO Auto-generated constructor stub
this.cityname = cityName;
this.lat = lat;
this.lng = lng;
this.path = "c:"+File.separatorChar+this.cityname+".xml";
System.out.println(path);
this.initXPath();
this.method1()
this.method2()
..
this.expr = "//node[#lat='"+this.lat+"'"+"]/following-sibling::tag[1]/#v";
this.xPath.compile(this.expr);
String s = (String) this.xPath.evaluate(this.expr, this.document, XPathConstants.STRING);
System.out.println(s);
}
So, for example, this constructor is loading a file, parsing it in XPath.. if I ever want to create a RoadInfo object, I can now only do it by loading files and having to worry about exceptions being thrown. This class also now becomes hilariously difficult to unit test because now you can't test the this.initXPath() method in isolation, for example - if this.initXPath(), this.method1() or this.method2() have any failures, then every one of your test cases will fail. Bad!
I would prefer it to look something more like this:
class RoadInfoFactory {
public RoadInfo getRoadInfo(String cityName, double lat, double lng) {
String path = this.buildPathForCityName(cityName);
String expression = this.buildExpressionForLatitute(lat);
XPath xpath = this.initializeXPath();
XDocument document = ...;
String s = (String) xpath.evaluate(expression, document, XPathConstants.STRING);
// Or whatever you do with it..
return new RoadInfo(s);
}
}
Never mind the fact that you have at least 5 responsibilities here.
Build OS-neutral path
Build XPath expression for latitude/longitude
Create XPath doocument
Retrieve s - whatever that is
Create new RoadInfo instance
Each of these responsibilities (Except the last) should be separated into their own classes (IMO), and have RoadInfoFactory orchestrate them all together.
The purpose of the constructor is to establish the class invariants, that is, to bring the newly created object into a state that then allows clients to use them. In general, it is bad practice for an object to be relying on extra initialisation after it's constructed. What you want to avoid is to write such things into the documentation as:
...after creating an instance of class X, remember to ALWAYS call
initX(), or bad things will happen!
Though in certain cases it's difficult to avoid it and the constructor can become quite messy. For example loading external files in a constructor is problematic.
In these cases there are two things you can do:
Rewrite your constructor so it requires the contents of the file instead of the name. Let the caller do the loading. The main difference is that you require the caller to do something before the object is created, and you can express it with the signature of your constructor: public RoadInfo(String cityName, Document cityDatabase, double lat, double lng) {...} Of course you can go even further and require the value of s straight away and let the caller do the XPath search. Note that all these steps move the class towards having a single responsibility, which is considered a good thing.
But now you require the caller to perform many steps before they can build your RoadInfo. This is where you can use factories, which perform this extra initialisation too and return fully built RoadInfo objects.
The most important thing though is that the constructor must not call any method of the object under construction that can be overridden. Calling private methods is fine, calling public methods on this is not a good idea unless the methods or the class itself is marked as final.
If you call such a method, there's always a chance that the class overriding the method does something that breaks your functionality, like exposing this to the outside world before the construction is completed. Here's an example:
public abstract class Foo {
public Foo(String param) {
if (this.processParam(param) == null)
throw new IllegalArgumentException( "Can't process param.");
}
protected abstract processParam(String param);
}
public class Bar extends Foo {
public Bar(String param) {super(param);}
protected processParam(String param) {
SomeOtherClass.registerListener(this); // Things go horribly wrong here
return null;
}
}
If you now call new Bar("x"), the constructor of Foo will throw an exception because it considers the parameter invalid. But Bar.processParam() leaked a reference of this to SomeOtherClass, potentially allowing SomeOtherClass to use the Bar instance that shouldn't even exist.
More typically, classes requiring heavy initialization would be provided to the client via a factory method. Constructors are often too restrictive—a random example being the inability to surround the super or this opening call with try-catch.
If you provide a public factory method, you can make the constructor private. The constructor can only do the easy work like assigning final fields, and the factory takes over. In the long run this is a more future-proof design. Many public libraries had to break their earlier API to introduce factories that allow their code to grow.
Is it a good practice to call some methods from the constructor?
Sadly the only good answer to this is It depends on the object.
If the object is intended to hold information then the answer must be probably not, try to avoid it because an object should really only do one thing.
If, however, the object is there to perform a function then by all means make sure that it is ready to perform that function by calling methods etc. If, for example it is a database connection then you might wish to connect to the database at construct time, or at least register itself in a connection pool.
It is, however, good practice to postpone any potentially slow stuff you can postpone until you need it. In my example of the database you may wish to postpone the actual connection to the database but you would certainly register the connection in the connection pool.
Sadly - the answer to the opposite question:
Is it a bad practice to call some methods from the constructor?
Is also It depends on the object for similar reasons.
There's no good practice, just bad practice that you should not do.
When you call a method within a constructor, some dangerous here are:
1) the method can be overwritten, and its subclass implement break your class's constraint protected by constructor, the implement is out of your control.
class T {
int v;
T() {
v = getValue();
}
int getValue() {
return 1;
}
}
class Sub extends T {
#Override
int getValue() {
return -1;
}
}
here T's v suppose to be 1 when you call new T(), but when you create a new Sub(), 'v' will be set to -1, which may break T's constraint, and this happens unconsciously.
2) the half-constructed object leaked, while it's status may be illegal.
class T {
int a, b;
T(C c) {
// status of "this" is illegal now, but visible to c
c.calc(this);
a = 1;
b = 2;
}
}
class C {
int calc(T t) {
return t.a / t.b;
}
}
3) something more I don't know...
if you can prevent all of them, you can do what you want.
(Try to keep exceptions not thrown. So the constructor can nicely initialize a field.)
Do not call overridable methods in the constructor.
About the pitfalls of an overridable method call in a constructor:
The evaluation of a (child) constructor is:
"Zero" all fields (0, null, 0.0, false)
Call the super constructor (implicit if not in code)
Call all field initializations (field declarations with = ...)
Do rest of constructor code
So:
class A {
A() { f(); }
protected void f() { }
}
class B implements A {
String a;
String b = null;
String c = "c";
B() {
//[ a = null, b = null, c = null; ]
//[ super();
// B.f();
//]
//[ b = null; ]
//[ c = "c"; ]
// "nullA" - null - "c"
System.out.printf("end %s - %s - %s%n", a, b, c);
}
#Override
protected void f() {
System.out.printf("enter f : %s - %s - %s%n", a, b, c);
// null - null - null
a += "A";
b += "B";
c += "C";
// "nullA" - "nullB" - "nullC"
System.out.printf("leave f : %s - %s - %s%n", a, b, c);
}
}
That behavior is quite muddying the waters, and here doing assignments that are immediately overwritten by field initializations.
A normal call one often sees in constructors is a setter, that maybe has some normalization code. Make that setter public final void setX(X x);.
Related
I saw some example of of using supplier interface at https://dzone.com/articles/supplier-interface.
My question is, if in the above example I could do something as easy as :
driveVehicle(new Vehicle());
driveVehicle(new Car());
Why would one want to use supplier interface, if all it does is call a method, without taking in any parameters.
Suppose you have parameters stored in database that you want to keep in constant all over your app
// Assume retrieveSystemParameter query database which allows to change parameters
public static String SYSTEM_PARAMETER = StaticUtilities.retrieveSystemParameter();
That value will be initialized once and won't change untill a redeployment. That being said, if instead you use a supplier :
public static Supplier<String> SYSTEM_PARAMETER_SUPPLIER = StaticUtilities::retrieveSystemParameter;
When you need the value somewhere you will call SYSTEM_PARAMETER_SUPPLIER.get() which will retrieve parameter in the database when needed - that way if you change a parameter in database, you won't have to redeploy.
As you can see, Suppliers are lazy. They do the work when you ask them to work (by calling .get()) - that may allow you some performance gain if you deal with them wisely. Sometimes you will call a method which expect a variable X passing in method retrieveX and then end up not needing X in the method because some conditions were not met. In that case you will lose performance as you will execute the code to retrieve X while a supplier that retrieve X would only execute it when calling .get and you would only do that call if the conditions were met.
Disclaimer : the system parameter constant is just the first example that came to my mind, but considering it query the database on each .get() you'd rather cache the parameter and have the cache call .get() at a specific interval.
I guess Optional might be perfect example. Consider the following snippet:
final Product firstProduct = Optional.ofNullable(product)
.orElse(productDao.findProductById(id));
final Product secondProduct = Optional.ofNullable(product)
.orElseGet(() -> productDao.findProductById(id));
You're getting a product that may be null. In order to determine firstProduct java will have to call expression in orElse method so no matter product is null or not you always have to determine value that will be returned in case product is null.
In order to determine secondProduct database doesn't have to be queried in case product is not null because you're passing a Supplier that will be called only if product is null.
Another example is when your method that accepts a supplier is not pure (i.e., it has side effect), and the side effect happens before calling the lambda, and the behaviour of the lambda is affected by the side effect.
Consider, for instance, this example:
public class TestClass {
private String field;
public String getField() {
return field;
}
public void method(Supplier<String> supplier) {
field = "This is";
System.out.println(supplier.get() + " a test");
}
public static void main(String[] args) {
TestClass c = new TestClass();
c.method(() -> c.getField());
}
}
Here, method() is not pure, as it changes the value of field, which is used later in the lambda (through calling the getField() method). As the lambda is called in place (i.e., when get() is called), calling getField() will happen after setting the field. In other words, method() accepts a Supplier<String> instead of a String in an attempt to let the clients safely call the getField() method.
Of course, having side effects should be avoided wherever possible, and this is just a toy example, but it shows a potential place where a supplier can be used.
Supplier adds one more level of indirection.
Given that "All problems in computer science can be solved by another level of indirection", it's likely that there are some problems that can be solved by using a Supplier.
Beware, however, of the corollary "...except for the problem of too many layers of indirection."
So, if there's no problem to solve, then Supplier is overkill and you should stick to directly invoking new.
Put differently: mistrust any "pattern" or "best practice" that doesn't start by explaining a problem (your question shows, you actually do mistrust, so just keep on asking this kind of questions).
I use it to avoid the unnecessary creation of additional states:
private Supplier<Boolean> detach = () -> false;
private Supplier<Boolean> isAttached = () -> false;
private Supplier<Integer> index = () -> null;
private final Function<List<ObserverWrapper<X, Y>>, Boolean> attachFun = observers -> {
isAttached = () -> observers.contains(this);
detach = () -> observers.remove(this);
index = () -> observers.indexOf(this);
return observers.add(this);
};
public boolean attach(List<ObserverWrapper<X, Y>> observers) {
return attachFun.apply(observers);
}
public boolean isAttached() {
return isAttached.get();
}
public Integer observerIndex() {
return index.get();
}
Which some would say is unnecessary in itself, but then it becomes a philosophical problem.
A problem which would not exist if computers didn't exist, and then it becomes a real world problem of indirection.
I may admit that suppliers for me may have become an addiction, but in my mind they feel like the natural extrapolation and extension of all the programming axioms and principles.
You could use a Supplier in a map based factory class
public class StackService {
final static String INTEGERS = "Integers";
final static String DOUBLES = "Doubles";
final static String STRINGS = "Strings";
final static Map<String, Supplier<Stack>> stackType;
static {
stackType = new HashMap<>();
stackType.put(INTEGERS, Stack<Integer>::new);
stackType.put(DOUBLES, Stack<Double>::new);
stackType.put(STRINGS, Stack<String>::new);
}
public Stack<?> createStackOfType(String stackType) {
return stackType.get(stackType).get();
}
}
Here if you were to just use new Stack() you would be returning a reference to the same object rather than a new one.
I'm doing a basic Java course and I came to a problem: How do I create an object only if I have passed valid parameters to the Constructor?
Should I make an alternate class and call the constructor from there after the validation is realized?
Or should/could I use a static method in the class for the validation?
What is the best practice in this case?
The standard practice is to validate the arguments in the constructor. For example:
class Range {
private final int low, high;
Range(int low, int high) {
if (low > high) throw new IllegalArgumentException("low can't be greater than high");
this.low = low;
this.high = high;
}
}
Side note: to verify that arguments are not null, which is fairly common, you can use:
import static java.util.Objects.requireNonNull;
Constructor(Object o) {
this.o = requireNonNull(o); //throws a NullPointerException if 'o' is null
}
UPDATE
To reply to your specific comment about social security number. One way would be to add a method to the class:
//constructor
public YourClass(String ssn) {
if (!isValidSSN(ssn)) throw new IllegalArgumentException("not a valid SSN: " + ssn);
this.ssn = ssn;
}
public static boolean isValidSSN(String ssn) {
//do some validation logic
}
The calling code could then look like:
String ssn = getSsnFromUser();
while(!YourClass.isValidSSN(ssn)) {
showErrorMessage("Not a valid ssn: " + ssn);
ssn = getSsnFromUser();
}
//at this point, the SSN is valid:
YourClass yc = new YourClass(ssn);
With that design, you have achieved two things:
you validate the user input before using it (which you should always do - users are very good at typos)
you have made sure that if YourClass is misused an exception is thrown and it will help you detect bugs
You could go further by creating a SSN class that holds the SSN and encapsulates the validation logic. YourClass would then accept a SSN object as an argument which is always a valid SSN by construction.
I'd just throw an IllegalArgumentException in the constructor itself:
public class MyClass {
private int i;
public MyClass (int i) {
// example validation:
if (i < 0) {
throw new IllegalArgumentException ("i mustn't be negatve!");
}
this.i = i;
}
A well-known truism in programming is 'Don't use Exceptions for flow control'. Your code should be aware of the restrictions and guard against them before calling the constructor rather than handling errors. Exceptions exist for expectational circumstances, especially ones that cannot be predicted or guarded against (for example, an IO stream may become invalid during writing, despite being OK during a previous check).
While you can throw exceptions in your constructor, this is not always ideal. If you are writing public objects that you expect to be used/reused by others, Exceptions are the only real option for public constructors, however such limitations and their result (e.g. what exception will be thrown) should be clearly documented in the javadoc for the class.
For internal classes, assertions are more appropriate. As Oracle states: "Assertions... should be used to check for cases that should never happen, check assumptions about data structures, or enforcing constraints on arguments of private methods."—Using Assertions in Java Technology. You probably should still document your expectations for the class, but your application should internally do any checks beforehand rather than relying on any Exceptions being thrown.
Static factory methods can help a little, their benefits are elaborating upon a bit by another question: How to use “Static factory methods” instead of constructors. However, they don't give strong validation options without, again, relying on Exceptions when things are not valid (that, or returning null, which is less informative).
Your ideal solution is the Builder pattern. Not only does it allow for a greater deal of flexibility in managing your arguments, you may validate each one individually, or have a validate method that can evaluate all the fields at once. A builder can and should be used to hide the object's actual constructor, enjoying sole access to it and preventing any unwanted values from ever being submitted, while assertions can guard against 'the builder should never submit these values'.
Constructors can throw exceptions (see Can constructors throw exceptions in Java?) so you can have your constructor throwing an exception if invalid values are passed. You can also make your constructor private and use the static method to create your object, that performs the checks. This might be cleaner.
One way to make sure you have valid parameters passed to the constructor is to create the parent class with constructors that only accept the parameters you require, then create a subclass that your end-users use. If you force your user to call super() and pass in your required parameters, then they have to at least pass in the right data objects. As far as valid values for those parameters, that's up to you whether you want to include validation in the parent class constructor and throw runtime exceptions or whatnot.
Here's an example of the superclass / subclass thing. Let's call the superlcass SomeShape and the subclass Triangle. For any SomeShape object, you are going to force the "user" to provide a number of sides and a side length. This is how...
public class SomeShape {
private int numSides;
private int sideLength;
public SomeShape(int mNumSides, int mSideLength) {
numSides = mNumSides;
sideLength = mSideLength;
}
}
public class Triangle extends SomeShape {
private int height;
public Triangle(int mNumSides, int mSideLength, int mHeight) {
super(mNumSides, mSideLength);
height = mHeight;
}
}
Aside from hard-coding a bunch of logic and exception throwing into your constructor, this is a relatively clean way to enforce what parameters are required to create the object.
If you don't want to throw an exception from the constructor, you could make the constructor private and create a static method that returns a new instance of the object, or null if the arguments are invalid. The caller of this method would have to check if the result is null or not, however.
Example:
public class Foo {
private Foo(int arg1, Bar arg2) {
// guaranteed to be valid.
}
public static Foo construct(int arg1, Bar arg2) {
// perform validation
if (arg1 < 0 || arg2 == null) {
return null;
} else {
return new Foo(arg1, arg2);
}
}
}
Usage
Foo object = Foo.construct(1, new Bar());
if (object == null) {
// handle error here.
}
It's bad practice to throw an exception out of a constructor. You end up with a partially initialized object, which is probably going to break all kinds of contracts.
If a constructor isn't valid for all combinations of inputs, it's cleaner to create a factory method that does the validation, and make the constructor private. If there's a real possibility of failure (that is, the failure isn't due to a programming error), then it might be appropriate to return an Optional.
I tried googling and searching for this question but somehow couldn't find anything relevant about it. I'm wondering if there is a bbest-practise guide on when to use attributes in a class and when not, but rather use parameters to the single methods.
Many cases are clear to me, e.g.
public class Dog
{
private name;
public setName(...) {....}
}
But sometimes it's not clear to me what's better to use.
E.g. the following, either use:
public class calculation
XYZ bla;
public calculation(XYZ something)
{
this.bla = something;
}
public void calc1()
{
// some calculations with this.bla
}
public void calc1()
{
// some more calculations with this.bla
}
public XYZ getBla()
{
return this.bla;
}
}
or maybe do:
public class calculation
public calculation() {}
public static XYZ calc1(XYZ bla) // maybe static, if not dependant on other attributes/instance-variables etc
{
// some calculations with bla
return bla;
}
public static XYZ calc1() // maybe static, if not dependant on other attributes/instance-variables etc
{
// some more calculations with bla
return bla;
}
}
I mean you can argue for both cases. I see advantages and maybe disadvantages for both different styles, but somehow I prefer the second one as far as long as there are not too many arguments/parameters needed. Sure, if I need many many more attributes etc., then the first one will be better, simpler etc. because I dont need to pass so many parameters to the method...
Just a question of personal style?
Or how to decide for one approach?
Thanks
EDIT: A better example: I'm curently doing much image processing and the question would be wether to store the image internally in the state of the object or not. I'm currently NOT doing it because I'm using static methods, and psasing the image itself I to each method:
public class ImageProcessing
{
/**
*
*/
public static Mat cannyEdges(Mat I, int low, int high)
{
// ...
return I;
}
public static Mat cannyEdges(Mat I)
{
return ImageProcessing.cannyEdges(I, ContourDetection.CANNY_LOWTHRES, ContourDetection.CANNY_HIGHTHRES);
}
/**
*
*/
public static Mat getHoughLines(Mat Edges, ...some_conf_vars...)
{
// ...
return I;
}
}
and then I'm calling it from the outside like this e.g.:
// here: read image to I...
Mat edges = ImageProcessing.cannyEdges(I, 20, 100);
Mat lines = ImageProcessing.getHoughLines(I);
// draw lines...
question is: Does I belong to the state of the object? Would it make sense to convert to non-static and then use for example:
// here: read image to I...
ImageProcessing IP = new ImageProcessing(I);
IP.cannyEdges(20, 100); // CHANGE OF cannyEdges: Also save `edges` internally as property!?
IP.calcHoughLines(); // also save the lines internally maybe?
Mat lines = IP.getLines();
// draw lines...
is this nicer?
The question arising is then again: Should I for example store the result of getHoughLines() (i.e. the lines) internally or should I directly return it to the caller!?
I can use some examples:
public class Multiplier {
private int number;
public Multiplier(int number) {
this.number = number;
}
public int multiply(int other) {
return number * other;
}
}
This class could be instantiated like:
Multiplier multiplyByTwo = new Multiplier(2);
I could use it to multiply many elements on a list by 2.
But I could need to multiply pairs of numbers. So the following class could be what I neeed:
public class Multiplier {
public static int multiply(int number, int other) {
return number * other;
}
}
I could make it static since no state is needed.
This example could be used like this on a list:
for (int x:listOfInts) {
print(Multiplier.multiply(x * 2));
}
But probably in this specific case the 1st example was nicer.
for (int x:listOfInts) {
print(multiplyByTwo(x));
}
or even nicer used with a Java 8 ''map''
If I need to get the elements of the multiplication and the result at many points in my code i could do.
class Multiplier {
private int x;
private int y;
public int multiply() {
return x * y;
}
// getters and setters for x and y
}
In this last case I may consider not adding setters and pass x, y in the constructor.
Every structure could be used in some specific cases.
It's not entirely a question of personal style. But nevertheless, I assume that this topic might be slightly controversial (opinion-based) and thus not perfectly suited for a Q/A-site.
However, the obvious question is: Does an object of the respective class really carry a state? That is, is there any benefit in having the state represented by an instance? If the sole purpose of the instance is to be an accumulator of variables that are modified with a sequence of set... calls and a final call to an execute() method, then there is usually no real justification for such an instance - except for avoiding to have a static method with "many" parameters.
I think that the advantages of static methods outweigh most of the potential clumsiness of calling a method with "many" parameters. One of the most important ones is probably that the approach with static methods doesn't increase the state space. Every field is another dimension in the state space, and documenting state space properly can be hard. Static methods enforce a more "functional" programming style: They don't have any side-effects, and thus, are thread-safe (which is becoming increasingly important).
(Note: All this refers to static methods that are not related to any static state - that should be avoided anyhow. And of course, this refers to methods that are not involved in or aiming at anything related to polymorphism).
And after all, one can easily call any static method from anywhere - even from within an instance method, and pass in some fields as parameters. The opposite is not so easy: When you want to call a method that depends on many instance fields, it can be a hassle when you first have to create an object and set the fields appropriately (still not knowing whether it is in a valid state to call the method). I also see the default methods of Java 8 as a nice application case where static utility methods come in handy: The default method may easily delegate to the utility method, because no state is involved.
There are a few reasons I'd go with the first option, i.e. an object with state over static functions, particularly for complex calculations but also for simpler ones.
Objects work better for the command pattern.
Objects work better for the strategy pattern.
Static methods can turn unit tests into a nightmare.
Static is an anti-pattern in OOP because it breaks polymorphism, with the side-effect that related techniques will break with it, e.g. open/closed, mocking, proxies, etc.
That's my 2c at least.
The weird part of your first example is that those calcX methods don't say anything about idempotency, so it's unclear what this.bla is when it's being manipulated. For complex computations with optional settings, an alternative is to construct an immutable object using a builder pattern, and then offer calcX methods that return the result based on fixed object state and parameters. But the applicability of that really depends on the use case, so YMMV.
Update: With your new code, a more OOP approach would be to decorate Mat. Favouring delegation over inheritance, you'd get something like
public class MyMat
{
private Mat i;
public MyMat(Mat i) {
this.i = i;
}
public Mat getBackingMat() {
return this.i;
}
public MyMat cannyEdges(int low, int high)
{
// ...
return new MyMat(I); // lets you chain operations
}
public MyMat cannyEdges()
{
return new MyMat(ImageProcessing.cannyEdges(I, ContourDetection.CANNY_LOWTHRES, ContourDetection.CANNY_HIGHTHRES));
}
public MyMat getHoughLines(...some_conf_vars...)
{
// ...
}
}
MyMat myMat = new MyMat(I);
lines = myMat.cannyEdges(20, 100).calcHoughLines();
This is just a guess, cause I have no idea what those things mean. :)
When not to use static:
If the result that will be returned is dependent on other variables (state) that make up your "calculation" class then static cannot be used.
However, if you are simply doing calculations on a variable, as the example implies, static is probably the way to go as it requires less code (For example to perform calc1 and then calc2 on a variable by the first method you would have to do:
calculation calc = new calculation(x)
calc.calc1();
calc.calc2();
XYZ y = calc.getBla();
while with the second example you could do
static import ...calculation.*;
...
XYZ y = calc2(calc1(x));
I have noticed a thing that a constructor and a simple method of a class do the same work. what is the exact reason to create a construct of a class? If i create MyClass(){} constructor and MyClassMethod(){} method it will do the same work as I write the body part of those method and constructor. So what is the need of construct? Does it have any special use ?
A constructor and a method are two different things. The fact that you can write the same or similar code inside them is irrelevant.
When a new object is created a constructor is called. If you don't specify one the compiler will create a default one for you. This is the place where initializaton of the object's fields takes place and memory is allocated for the object. This is a concept that all object-oriented languages have. A new object must be initialized somehow. Memory needs to be allocated. In Java you don't manage the memory yourself (at least not directly anyway) so this is the purpose of the constructor. Note that since a constructor is always executed, this behaviour is enforced as soon as you call e.g. Person p = new Person();.
Now since a constructor is always being called, you have an option here: do you let the default constructor execute or do you create one yourself? Perhaps there are fields that need to be initialized in a way other than their default values. Or perhaps you need to not allow creating an object without providing some values. If you define a constructor yourself, the compiler does not create a default one for you. So if I have public Person(String firstName, String lastName) {} then I have created a specific rule that is again enforced by the system: a new object of class Person cannot be created unless you give a first name and last name:
Person p = new Person(); // this would give a compile error
Person p = new Person("John", "Smith"); // this is the only way to create an object now
Using a method you cannot enforce this. The programmer using your class might call your method or not. The constructor is a part of the lifecycle of the object. Methods define the behaviour of the object
Some points :
1) Constructors are the only way to set final instance variables .
public class SomeType {
final int x ;
SomeType(int y){
x=y;
}
}
2) A class with private constructor cannot be sub classed.
3) If your class is a subclass and the base class doesn't have a default constructor , then you need a constructor in your class to call the super class constructor.
One of the benefits of using a constructor over a method is that you can be assured the constructor was called and the work within the constructor was performed.
The language specifies that to construct an object a constructor must be called. So if you use a custom method to establish the initial state of your object, you will need to call the default constructor first. Why make two method calls when you can perform the work in one call the constructor and be assured the object has been properly initialized?
public class Test(){
private Integer x;
public Test(){
}
public Test(Integer x){
this.x = x;
}
public void setX(Integer x){
this.x = x;
}
public void doSomethingWithX(){
this.x.toString();
}
}
Test test = new Test(8);
test.doSomethingWithX(); //I know x has been declared and assigned
Test test = new Test();
test.doSomethingWithX(); //X has not been assigned results in NPE
If you create a new Object of MyClass it will automatically call the constructor - you can initialize all members within it, and be sure that this object´s members are all initialized.
Generally:
A constructor is always called once when you create a new Object of this class, and you can´t call it manually.
And don´t do "real" work in a constructor, as it will slow down the creation of objects of this class - only initialize your class/members there.
You can also use different constructors, depending on your needs - but if you create a constructor, there is no more default constructor!
Example:
public MyClass {
int score;
public MyClass(int sc) { // already know the score
score = sc;
}
public MyClass() { // don´t know the score yet
score = 1;
}
public void addScore() {
score += 5; // i know for sure that score is not zero
}
}
Essentially a constructor is just a special method that implicitly returns an object of its containing type. You should generally use constructors for creating objects - this is what people expect to see.
However, there is a useful idiom called the factory method (more info at this link) which is essentially using a static method to construct an object, the key advantages being
You can give a factory method a more descriptive name (whereas of course a standard constructor has to be named after the containing class).
They don't have to return an object, giving more flexibility.
They can return a sub-types of the class.
You can set final fields without initializer in a constructor. This helps to build immutable instances:
class Number extends Expr {
private final int n;
public Number(int n) {
this.n = n;
}
public int getValue() {
return this.n;
}
}
So after a constructor like this, you can rely on the fact that the instance is initialized completely (and in this case, it's values are immutable/constant).
Constructor is not like simple methods. It is called every time when the object of that particular class is created. You don't need to call it explicitly.
There are somethings that we need to do immediately when the object is created, for instance when you create a GUI kind of thing you want to set many properties on the time of creation like size of window etc.
Another benefit of constructor is security of class. You cannot create a object unless you know the right perimeters of constructor.
More details:http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
A constructor is a special method of a class or structure in object-oriented programming that initializes an object of that type.
Some points :
1. A constructor eliminates placing the default values.
2. A constructor eliminates calling the normal method implicitly.
These are the benefits of constructors.
Automatic initialization of objects at the time of their declaration.
Multiple ways to initialize objects according to the number of
arguments passes while declaration.
The objects of child class can be initialised by the constructors of base class.
I am having some trouble understanding classes in Java.
Such as how do you declare "Inputter" in the helper class like this?
public class Helper
{
public void Helper(String z)
{
if(z.length() == 0)
{
System.out.println("You can't leave it blank!");
System.exit(1);
System.out.println("It's not working... ;(");
}
}
public void Inputter(int a)
{
// blah blah
}
}
Would you call it like this?
Helper x = new Inputter();
Please help, and NO this is NOT a homework question.
Thanks,
Smiling
EDIT: Would this be right:
public class Helper
{
public Helper(String z)
{
if(z.length() == 0)
{
System.out.println("You can't leave it blank!");
System.exit(1);
System.out.println("It's not working... ;(");
}
}
public void Inputter(int a)
{
// blah blah
}
}
and declared with:
Helper x = Helper();
And thanks everyone for giving me a warm welcome to StackOverflow! :D
Your problem is not with classes, it is with constructors and methods, and the difference between them.
Methods can have any name you like, they must declare a return type (possibly void), and they're called like this:
ReturnType r = methodName(param1, param2)
Constructors are used to create instances of classes (objects). They must have the same name as the class, they must not have a return type (not even void), and they're called like this:
MyClass m = new MyClass(param1, param2);
There are several problems in your code:
Helper has the correct name for a constructor, but because it declares a void return type, the compiler will treat it as a method.
Inputter doesn't even have the correct name for a constructor. To use it as a constructor with new, it would have to be part of a class called Inputter
Perhaps you should start out reading the introduction to OO part of the Java tutorial.
Inputter() that you have defined is a method or you can call it a behavior. You cannot create an instance for a behavior.
One more problem is that you cannot have return types on a constructor. Helper is the class name and the constructor is having a return type which is incorrect
Regarding your quesiton, if you want to call Inputter, you should do it something like the following.
Helper helper = new Helper("test");
helper.Inputter(100);
It is a good practice to start methods with smaller case letters.
The only object here is Helper. If you want to make a new helper, then you will instantiate it by saying
Helper X = new Helper("blah blah");
If you want to call Inputter then you just say
X.Inputter(1234);
Which will call the Inputter function for the specific instance X of Helper
You must create an instance of Helper Before you can use Inputter:
Helper x = new Helper("some string");
to use Inputter, try this:
//create a new helper
Helper x = new Helper("some string");
//use the Inputter method of the helper.
x.Inputter(1);
The thing to understand here is that Helper is the class, x is an instance of a class, and Inputter is a instance method (which is different from a static method) in the Helper class.
Inputter in your code is not a class. It is a method.
To make following statement correct:
Helper x = new Inputter();
you would need to create Inputter class that extends Helper class.
Inputter is not a class. It's a method of the Helper class. So you cannot instantiate it.
You can call it like this
String someString = "some string";
Helper x = new Helper(someString);
int someInt = 1;
x.Inputter(someInt);
The new keyword is reserved for instantiating (fancy word for saying "making new") classes. The way your class is made, when you make a new Helper, a function is run. That is the construct function, and is named like the class.
Once you instantiate a class, you gain access to the goodies within it (exception is a static method/attribute, where anyone can access it); all within the class that isn't private or protected.
Now, a short intro on OOP (Object Oriented Programming):
You have classes, which are basically blocks of functionality. Within these classes are two things: Methods and Attributes (many names for that, but that's what I call them.)
A Method is basically a good ol` function: It has an input and an output.
An attribute is really like any other variable.
Now, in Java and many other OO languages, there's a separation between the class declaration and class instances. A class declaration is basically the static coded class; exactly what you put in the code. A class instance is taking the class declaration and putting it into use: You can change and use the methods and attributes inside them.
So, if you want to call Inputter, you should do it like this:
Helper bob = new Helper('Bloop');
bob.Inputter(42);
What happened here? We made a new variable called bob which has a type of Helper. When constructing the new Helper, we also run the constructor. Looking at the constructor function, we pass a value to it (in this case, 'Bloop'), and the function is run normally, without us having to manually call it.
Now we want to use the Helper class' Inputter method. For that, we need to access an instance of the Helper class (in our case bob), by using bob. (notice the dot), and then calling it like any other function: Inputter(parameters). Gluing it together we get bob.Inputter(parameters)
This was a really rather lame explanation of Object orientation that didn't cover that much, but it should get you started. I recommend getting a book about Java or reading online tutorials.
First, start with the basics.
Classes best represent nouns. That means a Class is a model of (typically) a thing. Methods best represent verbs on those nouns. Drifting away from this ideal is sometimes necessary; however, the further you stay away from such an ideal, the harder it will be to understand what is going on. With a nod to the exceptions, since you're a beginner let us not get wrapped up in the exception but follow the rule.
public class Person {
private String name;
private int age;
public Person(String name) {
this.name = name;
this.age = -1;
}
public void setAge(int value) {
if (value < 0) {
throw new IllegalArgumentException("Age must be greater than zero");
}
this.age = value;
}
public int getAge() throws IllegalStateException {
if (age < 0) {
throw new IllegalStateException("Age was not set");
}
return this.age;
}
}
Read through the class above, and use its style for your beginning programs. When you find that its style is hindering you more than helping you, then you might have found a place where other techniques are needed.