0

Consider a rectangle and a square. If we treat them as objects it is clearly evident that a square can inherit most or all of its properties from a rectangle, since a square is a special case of a rectangle. The only restriction is that a square must have similar side lengths.

Take a look at this very basic implementation.

class Rectangle(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def get_area(self):
        return self.x * self.y


class Square(Rectangle):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.x != self.y:
            raise ValueError("x and y must be equal.")

Type-checking is avoided for simplicity. I used args and kwargs inorder to make sure that the subclass(es) will be future proof. I am, however, not sure if I am doing it right. Rectangle class' __init__ might add more arguments in the future.

The question is, if x and y must be equal, why ask for both of them in the first place? Shouldn't there be only one of them? The current inheritance scheme has this restriction - the user is forced to enter x and y. How can this problem be solved. Turning x and y in to keyword arguments is not a solution, since no defaults (or None) are allowed.

2
  • 1
    Attempting to define Square as a subclass of Rectangle is a classic violation of the Liskov Substitution Principle precisely because of this issue. Commented Jul 31, 2015 at 20:11
  • 2
    @chepner: Although, as the article notes, that depends on what the API of the class is. If modifying the dimensions after creation is not a supported operation, then there's no problem. Commented Jul 31, 2015 at 20:13

1 Answer 1

7

You can do this:

class Square(Rectangle):

    def __init__(self, x):
        super().__init__(x, x)
        if self.x != self.y:
            raise ValueError("x and y must be equal.")

If you want to add *args and **kwargs you can. However, as an aside, this will not make anything "future proof" if you pass the *args and **kwargs to Rectangle, because Rectangle does not accept them.

Sign up to request clarification or add additional context in comments.

3 Comments

Probably no need to check if you're setting it yourself :-)
@ReutSharabani: The check might still make sense as an assert, since if it fails, something has gone fundamentally wrong.
@ReutSharabani: The original code is presumably doing the check to make sure the superclass did the right thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.