-3

I was going through the concept of final class in java which says final class can't be inherited in java. However, if we can make all the methods of class as final and all the variables as private, won't it create the same effect as that of declaring class as final?

Take the following scenario:

Let me describe my question bit more, One of the key requirements to make class immutable is- Class should be declared as final. All variables should be final (and initialized via constructors)

Can we achieve this immutability requirement by making all methods of class as final and declaring all variables as private and final, to achieve this condition for immutability?

So, even if the class can be inherited now, we can't override the methods (as methods are final) and we can't change the variables of super class (as they are final and also not visible - private).

luk2302
  • 55,258
  • 23
  • 97
  • 137
aquesh
  • 9
  • 1
  • 1
  • 8
  • 2
    No. You can declare a class with all the variables and methods as final, and that wouldn't stop you subclassing it. – khelwood Nov 28 '19 at 15:29
  • 3
    that won't prevent you from creating a class inheriting from this one and adding new methods – jhamon Nov 28 '19 at 15:29
  • Yes true, it won't prevent from subclassing, but can that subclass holds power to impact the super class in any way, which could not have been possible if superclass was declared final? I am talking about impact here, not whether we can or can't inherit. – aquesh Nov 28 '19 at 15:32

1 Answers1

2

No. Making a class final and making its variables and methods final are different things.

When you make a class final, it can't be subclassed. That's all that final means for classes. A final class can have non-final variables (but its methods are implicitly final, yes). Example:

final class Foo {
    private int counter;

    public int increment() {
        return ++this.counter;
    }
}

When you make a method final, it can't be overridden in a subclass. When you make a variable final, it can't be modified. Even if all of a classes variables and methods are final, the class can still be subclassed, and new methods can still be added. Example:

class Foo {
    public final void method1() {
        System.out.println("method1");
    }
}
class SubFoo extends Foo {
    public void method2() {
        System.out.println("method2");
    }
}

Re your fairly significant edit:

Can we achieve this immutability requirement by making all methods of class as final and declaring all variables as private, to achieve this condition for immutability?

No, because the class can still be subclassed, and the subclass can add non-immutable features:

class Foo {                 // Immutable
    private final int x;

    public Foo(int x) {
        this.x = x;
    }

    public final int getX() {
        return x;
    }
}

class SubFoo extends Foo {  // NOT immutable, thanks to `y`
    private int y;

    public SubFoo(int x, int y) {
        super(x);
        this.y = y;
    }

    public int getY() {
        return this.y;
    }

    public void setY(int y) {
        this.y = y;
    }
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    I really think nothing is wrong – J. Lorenzo Nov 28 '19 at 15:44
  • @T.J.Crowder Can you answer the question now, I think you have very well explained the use of final keyword, however with the latest edit my question is more towards final & immutability of class concepts. – aquesh Nov 28 '19 at 15:47
  • @aquesh - Already updated. It's best to avoid changes quite that big, though, when you can. – T.J. Crowder Nov 28 '19 at 15:48
  • @aquesh - If your reference to `SubFoo` is of type `Foo`, then it's true that *through that reference* you can't change anything on it. That doesn't make the object immutable, though. It just means that the `Foo` parts of it are immutable. – T.J. Crowder Nov 28 '19 at 16:00
  • 1
    This explains it well, thanks @T.J.Crowder To summarize: SubFoo is mutable (although the super class part of it is immutable). Any object created via Foo reference, Foo obj = new Foo(10) is always immutable – aquesh Nov 28 '19 at 16:08