0

Here, AsciiChecker enables the matrix specification in the text form.

abstract class AsciiChecker extends AlgoritmicChecker {

    String[] ascii;

    AsciiChecker(String title, final String ... ascii) {
        super(title, ascii[0].length(), ascii.length); // calls isCovered
    };

    boolean isCovered(int test, int statement) {
        return ascii[statement].charAt(test) == '1';
    }           
}

It needs the matrix argument to be available in the isCovered call. Tell me how do I shoot my leg if I initialize the field before using it,

    AsciiChecker(String title, final String ... ascii) {
        this.ascii = ascii;
        super(title, ascii[0].length(), ascii.length); // calls isCovered
    };
Val
  • 1
  • 8
  • 40
  • 64
  • 1
    `// calls isCovered` -> Which part of your code calls it? We can't see any such invocation. – Rohit Jain Oct 24 '13 at 13:01
  • This part of code is called a constructor. Constructor is a method that can call other methods. One of the methods it calls is the `isCovered()` . If you cannot still imagine it, think of super() as `for each x in width, for each y in height, print(isCovered(x,y))`. – Val Oct 24 '13 at 13:42
  • Sorry, I still can't imagine it. Are you calling `isCovered()` method from super class constructor? – Rohit Jain Oct 24 '13 at 13:43
  • 1
    This is why constructors shouldn't call overrideable methods! – artbristol Oct 24 '13 at 13:46
  • Can you prove that calling overridable is worse than initializing extended fields prior super constructor? – Val Oct 24 '13 at 13:47

2 Answers2

1

If your superclass is using data your array, pull up String[] ascii; to the superclass, initialize this field there and in isCovered access it via getter or modify signature of isCovered and pass proper array as an argument.

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • The difference between `Ascii` and `Algoritmic` classes is that `Algoritmic` does not need the ascii array for its operation. It is terrible to pull all the garbage into the basis class. Might be we should put everything right into the java.Object? How do you call this pattern? – Val Oct 24 '13 at 13:46
  • Than you have to exclude your `validation` logic out from constructor and declare validation method in your super class, and call it externally after your object is created (and ascii field is initialized) or redefine superclass coustructor to allow additional parameter to be passed. If this doesn't suit your needs or thinking, than you must redesign your classes. The biggest sin I think (and obstacle) is that you have unnecesery login inside super constructor - extract it into method. – Antoniossss Oct 24 '13 at 13:49
  • This is what I also dislike about Java OOP. They say that constructor must not do all the construction. – Val Oct 24 '13 at 13:52
  • Well thats how Java works and we have to deal with it. Anyway I think it is not bad design. Constructors are for initializing objects, not for executing some fancy logic (as validation, connecting to external resources etc.) – Antoniossss Oct 24 '13 at 13:55
  • Furthermore, it is forbidden to complain that you have to do the initialization outside the constructor because, by definition, once constructor has exited, java object has completely initialized. But let me not to buy this manipulation. If I need to do a thing every time the object is created, it is not a fancy logic, it is object initialization. – Val Oct 24 '13 at 14:07
  • Objects are not costructing itself, other code has to create them. So what stands in the way for that "other" code to take a part in object construction? Besides, you actually CAN implement behaviour you desire by implementing post construction method - last method called by constructor. It can be overriden later on, and do things that constructors cannot do. But this is just the same approach I have described earlier - to put fancy logic in methods and invoke as needed. – Antoniossss Oct 24 '13 at 16:00
  • What you say is that fancy methods cannot be included into initialization and which methods are fancy the fancy methods are those that cannot be included into the initialization. This is a manipulation. I also do not buy your statement that constructors do not create objects. – Val Oct 24 '13 at 16:45
  • Actually you rename the parts of constructor into "fancy methods" in order to defeat `incapsulation`. When thing must always be performed every time the object is created, this procedure must be incapsulated into the constructor. It is ridiculous which manipulation anti-OOP methods do people employ just to justify a silly java designer's whim. – Val Oct 30 '13 at 11:31
  • What if initialization is complex, time consumming and throws exceptions - recovery from such situation could need partial result initialization. How to retrieve them if there is no object to reffer to? Pass dozen of objects with exception object level up or via dedicated container? That would make things less complicated for sure. Besides, what is your point in all? – Antoniossss Oct 30 '13 at 11:40
0

You need to get rid of that call of an overrideable method in the superclass. From Effective Java, item 18:

Move the body of each overridable method to a private "helper method" and have each overridable method invoke its private helper method. Then replace each self-use of an overridable method with a direct invocation of the overridable method's private helper method.

artbristol
  • 32,010
  • 5
  • 70
  • 103