class Cal
attr_reader :v1, :v2
attr_writer :v1
@@_history = []
def initialize(v1,v2)
@v1 = v1
@v2 = v2
end
def add()
result = @v1+@v2
@@_history.push("add : #{@v1}+#{@v2}=#{result}")
return result
end
def subtract()
result = @v1-@v2
@@_history.push("subtract : #{@v1}-#{@v2}=#{result}")
return result
end
def setV1(v)
if v.is_a?(Integer)
@v1 = v
end
end
def getV1()
return @v1
end
def Cal.history()
for item in @@_history
p item
end
end
def info()
return "Cal => v1 : #{@v1}, v2 : #{@v2}"
end
end
class CalMultiply < Cal
def multiply()
result = @v1*@v2
@@_history.push("multipy : #{@v1}*#{@v2}=#{result}")
return result
end
def info()
return "CalMultiply => #{super()}"
end
end
class CalDivide < CalMultiply
def divide()
result = @v1/@v2
@@_history.push("divide : #{@v1}/#{@v2}=#{result}")
return result
end
def info()
return "CalDivide => #{super()}"
end
end
c0 = Cal.new(30, 60)
p c0.info()
c1 = CalMultiply.new(10, 10)
p c1.info()
c2 = CalDivide.new(20, 10)
p c2.info()
하위 클래스가 상위 클래스에서 이미 정의된 `__init__` 메서드를 그대로 사용할 경우, 하위 클래스에서 `__init__` 메서드를 정의할 필요가 없습니다. 상위 클래스의 `__init__` 메서드가 하위 클래스의 인스턴스를 초기화할 때 그대로 사용되기 때문입니다.
### 상속과 `__init__` 메서드
- **상위 클래스**에서 `__init__` 메서드가 정의되어 있으면, 하위 클래스는 이를 자동으로 상속받습니다. 하위 클래스가 `__init__` 메서드를 따로 정의하지 않으면, 상위 클래스의 `__init__` 메서드가 하위 클래스의 객체 초기화에 사용됩니다.
- **하위 클래스**가 `__init__` 메서드를 따로 정의하면, 상위 클래스의 `__init__` 메서드를 덮어쓰게 됩니다. 그러나, 하위 클래스에서 상위 클래스의 초기화 동작을 유지하면서 추가적인 초기화 작업을 하고 싶다면, 하위 클래스의 `__init__` 메서드에서 `super()`를 사용하여 상위 클래스의 `__init__` 메서드를 호출할 수 있습니다.
### 예시
상위 클래스 `Cal`에서 `__init__` 메서드가 정의되어 있고, 하위 클래스 `CalMultiply`와 `CalDivide`에서는 `__init__` 메서드를 따로 정의하지 않았습니다. 이 경우, 하위 클래스의 인스턴스를 생성할 때도 상위 클래스의 `__init__` 메서드가 호출되어 `v1`과 `v2`의 초기화가 이루어집니다.
```python
class Cal(object):
def __init__(self, v1, v2):
if isinstance(v1, int):
self.v1 = v1
if isinstance(v2, int):
self.v2 = v2
# 기타 메서드들...
class CalMultiply(Cal):
def multiply(self):
return self.v1 * self.v2
# 기타 메서드들...
class CalDivide(CalMultiply):
def divide(self):
return self.v1 / self.v2
# 기타 메서드들...
```
### 하위 클래스에서 `__init__` 메서드를 정의할 필요가 있는 경우
하위 클래스에서 `__init__` 메서드를 정의해야 하는 경우는 다음과 같습니다:
1. 하위 클래스에서 상위 클래스의 초기화 외에 **추가적인 속성**이나 **초기화 작업**이 필요한 경우.
2. 상위 클래스의 `__init__` 메서드를 **변경**하거나 **확장**해야 하는 경우.
이 경우, 하위 클래스의 `__init__` 메서드에서 `super()`를 사용하여 상위 클래스의 초기화를 먼저 수행한 후, 하위 클래스의 고유한 초기화를 추가할 수 있습니다.
### 예시
```python
class Cal(object):
def __init__(self, v1, v2):
if isinstance(v1, int):
self.v1 = v1
if isinstance(v2, int):
self.v2 = v2
class CalMultiply(Cal):
def __init__(self, v1, v2, v3):
super().__init__(v1, v2) # 상위 클래스의 초기화
self.v3 = v3 # 하위 클래스의 고유한 초기화
자식 클래스가 부모 클래스와 같은 이름의 메소드를 만들면 자식 클래스의 메소드가 부모 클래스의 메소드를 override해서 자식 클래스의 메소드가 실행된다. 부모 클래스에서 같은 이름의 메소드를 실행시키기 위해서 파이썬은 super().메소드명()을 사용하고, 루비는 super()만 사용한다. 파이썬의 super()는 부모클래스 자체를 가리키는 반면, 루비의 super()는 super()가 쓰인 메소드와 같은 이름의 부모 클래스 메소드를 불러온다. 감사합니다!
기본적으로 아톰은 현재 OS에 이미 설치된 2.x 버전으로 코드를 실행합니다. 따라서 코드를 실행하는 파이썬 엔진의 버전을 변경할 필요가 있는데요, 아래 링크를 보시고 따라하시면 됩니다. 링크가 이해 안 되시는 분은 구글에서 atom python3 이라고 치시고 검색해보시면 비슷한 해결법이 많이 나오니 참고하시면 되겠습니다. https://hellobaek.tistory.com/7
python 3 버전을 쓰는데도 계속 super() takes at least 1 argument (0 given)이러한 오류가 나서 진도를 나가지를 못하고 있네요.
인터넷에서 찾아봐도 3.0버전에서 개선이 되서 super() 저 괄호 안에 특정 요소가 없어도 이고잉 님의 코드대로 적으면 오류가 안 날 것 같은데 계속 나는 이유 혹시 알 수 있을까요?