머리말
"Java 및 C ++에서 부모 클래스 기능에 대한 서브 클래스의 접근성을 줄이는 문제"라는 제목은 더 학문적 인 것으로 보이지만 실제로 무시하기 쉬운 문제입니다. 이 기사는 Java와 C ++ 의이 문제의 차이점을 자세히 설명하기 위해 노력합니다.
먼저, 우리는 부모 클래스 함수 커버리지에 대한 "서브 클래스의 접근성 감소"를 소개합니다. 상속의 경우, 하위 클래스는 상위 클래스의 "가상 함수"를 무시할 수 있습니다. Java에는 가상 함수라는 용어가 없지만 모든 Java 함수는 모든 Java 함수로 간주 될 수 있습니다. 모든 Java 함수는 서브 클래스에 의해 상환 될 수 있기 때문입니다. 여기서 우리는 "가상 함수"라는 용어의 의미 만 빌리며 언어의 세부 사항을 파헤치지 않습니다. Java와 C ++는 모두 재정의 할 때 기능의 접근성을 변경할 수 있습니다. 소위 "접근성"은 공개, 보호 및 개인과 같은 액세스 제어 문자를 사용하여 기능에 액세스 할 수 있는지 여부를 제어하는 것입니다. 일반적으로 접근성 순서는 (C ++에 패키지 개념이 없기 때문에, 패키지 액세스 제어는 당분간 고려되지 않으므로 여기서 논의에 영향을 미치지 않습니다).
공개> 보호> 개인
Java를 예로 들어보십시오.
클래스베이스 {protected void sayhello () {system.out.println ( "Hello in Base"); }} class child 확장 기반 {public void sayhello () {System.out.println ( "Hello In Child"); }} 참고 : sayHello() 기능은 여기에 있습니다. 상위 클래스 기반 에서이 함수는 보호 된 액세스 제어 문자를 사용하여 수정됩니다. 서브 클래스는 대신 공개를 사용하면 아무런 문제가 없습니다. 서브 클래스가 상위 클래스 함수를 무시할 때, 접근성 확장은 일반적으로 문제가되지 않습니다.
Java 및 C ++는 서브 클래스가 학부모 클래스 기능에 대한 접근성 재정의를 줄일 때 다른 전략을 채택합니다.
먼저 Java를 예로 들어 다음 코드를 살펴보십시오.
클래스 기반 {public void sayhello () {System.out.println ( "Hello In Base"); }} class child 확장 기준 {private void sayhello () {system.out.println ( "Hello In Child"); }}위의 코드에는 강조 표시된 8 행에 컴파일 오류가 발생합니다.이 코드는 전혀 컴파일 할 수 없습니다! Java는 부모 클래스 기능을 덮어 쓰면 서브 클래스가 접근성을 줄이는 것을 허용하지 않습니다. 이유에 관해서는 예제를 사용하여 설명 할 수 있습니다. 예를 들어, 우리는 수업 외부에 다음 코드를 작성합니다.
Base Base = New Base (); base.sayhello (); base = new child (); base.sayhello ();
이전 코드를 컴파일 할 수 있다면 기본이 새 base ()를 가리키면 sayhello ()에 액세스 할 수 있지만 기본이 새 Child ()를 가리키면 sayhello ()에 액세스 할 수 있습니다! Java의 관점에서 볼 때 이것은 모순 이며이 문제는 피해야합니다. 따라서 Java는 위의 코드를 쓸 수 없다는 컴파일러의 관점에서 규정합니다.
C ++의 경우 상황이 다릅니다. C ++ 예를 살펴 보겠습니다.
클래스베이스 {public : virtual void sayhello () {std :: cout << "hello in base"; }} 클래스 아동 : 공공 기지 {private : void sayhello () {std :: cout << "Hello In Child"; }}이 코드는 C ++에서 완전히 정확합니다. 여기서 서브 클래스는 부모 클래스 함수를 덮어 쓰면 접근성을 줄입니다. 문제가 없으면 클래스 밖에서 다음 코드를 쓸 수 있습니다.
어린이; child.sayhello (); // sayhello ()가 static_cast <base &> (child) .sayhello ()이므로 컴파일 할 수 없습니다. // sayhello ()가 공개되어 있기 때문에 컴파일 할 수 없습니다
어린이의 경우 sayHello() 가 개인이므로 외부로 호출 할 수 없기 때문에 2 행 전화가 실패합니다. 그러나 STATIC_CAST를 사용하여 아이를 기본 물체로 캐스팅하면 기본의 경우 sayHello() 가 공개되므로 정상적으로 호출 할 수 있습니다.
이를 위해 다음 예제는 C ++ 표준 멤버 액세스 제어 장의 가상 함수 섹션에 대한 액세스에서 찾을 수 있습니다.
클래스 B {public : virtual int f ();}; 클래스 d : public b {private : int f ();}; void f () {d d; b* pb = & d; d* pd = & d; pb-> f (); // ok : b :: f ()는 public, d :: f ()는 pd-> f (); // 오류 : d :: f ()는 private}입니다.이와 관련하여 C ++ 표준은 다음과 같이 설명합니다.
멤버 함수가 호출되는 객체 (위의 예에서 b*)를 나타내는 데 사용되는 표현식 유형을 사용하여 호출 지점에서 액세스가 확인됩니다. 정의 된 클래스에서 멤버 함수의 액세스 (위의 예에서 d)는 일반적으로 알려져 있지 않습니다.
간단한 번역에는 두 가지 핵심 사항이 있습니다.
이로 인해 C ++ 발신자는 일부 숙련 된 변형을 통해 원래 접근 할 수없는 호출 기능을 "영리하게"호출 할 수있는 것 같습니다. 보다 실용적인 예는 다음과 같습니다. QT에서 QObject::event() 함수는 공개적이며 서브 클래스 qwidget event() 함수는 보호로 변경됩니다. 자세한 내용은 관련 Qt의 관련 코드를 읽을 수 있습니다.
요약하면, 서브 클래스가 부모 함수를 무시할 때 Java는 서브 클래스가 기능 접근성을 좁힐 수 없다고 엄격히 제한하지만 C ++는 이러한 제한을 가지고 있지 않습니다. 개인적으로, 나는 소프트웨어 엔지니어링의 관점에서 Java 규정이 의심 할 여지없이 더 많은 엔지니어링의 중요성을 가지고 있으며 기능의 호출이 더 일관성이 있다고 생각합니다. C ++ 표준은 컴파일러 구현을 크게 단순화하지만 엔지니어링에 대한 좋은 참조는 아닙니다.
추신 : C ++ 표준의 공식 버전은 구매가 필요하지만 드래프트는 무료로 다운로드 할 수 있습니다. C ++ 표준 초안의 다운로드 주소는 다음 페이지에서 찾을 수 있습니다 : https://isocpp.org/standard
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.