자바 객체 지향 기반의 요약 제 2 조

상속, 캡슐화, 다형성 자세한 요약 : 객체 지향 세 가지 특성을 중심으로이 논문.

상속

왜 우리는 상속해야합니까?

"확장", "이해 수단을 확장 할 수있는 영어 문자 적 ​​의미에서, 상속은 서브 클래스가 특성과 코드 재사용을 달성하기 위해 상위 클래스의 동작을 상속 수 있도록 우리가 더 쉽게 바퀴를 재발견 할 필요가 없습니다, 확장 클래스, 상속을 달성 할 수 있습니다.

생명 상속

일치의 논리에 맞춰 상속 : 한 것은 이런 종류의 패스를 말할 수로, 상속의 종류, "XX는 XX입니다".


그림 : 포유 동물 와서는 포유 동물이 동물로부터 상속되는 것을 나타내는 의미가 할 수있는 동물, 고양이, 포유 동물이며,이 고양이는 포유류에서 상속되는 것을 나타내는 의미를 만들 수 있습니다 .

//示例
public class Test {
  public static void main(String[] args) {
    Student s = new Student(18,"芮耳朵","Java");
    s.study();//继承了父类Person中的方法
    s.play();
  }
}
class Person {
  int age;
  String name;
  public void study() {
    System.out.println("每天进步一点点!");
  }
}
class Student extends Person {
  String major;
  public void play() {
    System.out.println("我喜欢打篮球");
  }
  //构造方法
  public Student(int age, String name, String major) {
    //拥有父类的所有属性
    this.age = age;
    this.name = name;
    this.major = major;
  }
}

/*运行结果是:喜欢Java,每天进步一点点!
             我喜欢打篮球*/

复制代码

instanceof를 연산자

instanceof를 이항 연산자, 중국어로 해석이다 "... 예"객체의 왼쪽 피연산자는 오른쪽 클래스는, 피사체가 생성 된 개체 클래스의 왼쪽에서 오른쪽으로 할 때, 반환는 true, 그렇지 않은 경우는 false

//示例
public class Test {
  public static void main(String[] args) {
    Student s = new Student(18,"芮耳朵","Java");
    System.out.println(s instanceof Person);
    System.out.println(s instanceof Student); 
  }
}
//运行结果都是true。复制代码

주요 포인트 상속을 요약

  • 자바 만 단일 상속은 C ++ 다중 상속은 그런 종류처럼되지 않습니다. 다중 상속은 시스템을 유지하기 어려운 복잡 상속의 체인을 만드는 혼란 스러울 수 있습니다.
  • 자바 클래스는 클래스, 인터페이스, 다중 상속을 상속하지 않습니다.
  • 서브 클래스는 모든 속성과 부모 클래스 (부모 클래스 생성자 제외) 방법을 얻기 위해, 부모 클래스를 상속, 그러나 반드시 그러한 속성과 개인 부모 클래스의 메서드로 직접 액세스 할 수 있습니다.
  • 당신이 클래스를 정의하지 않으면 호출하지 않는 그것은 부모 클래스, 확장 : java.lang.Object 상위.

오버로드 된 메소드 (과부하)

상기와 동일한 방법 이름의 복수의 정의 될 수 과부하 클래스의 방법이지만 방법의 다양한 파라미터를 지칭한다. 호출되면, 자동으로 다른 매개 변수에 대응하는 매칭 방법.

오버로드 방법, 그냥, 실제로 같은 이름의 완전히 다른 접근 방식입니다!

구성 조건 : 매개 변수의 유형, 새로운 매개 변수, 다른 순서로 새로운 매개 변수의 수

//示例
public static int add(int n1, int n2)public static int add(int n1, int n2, int n3)
//方法名相同,参数个数不同,构成重载。
public static int add(int n1, int n2)public static double add(double n1, int n2)
//方法名相同,参数类型不同,构成重载。
public static int add(int n1, int n2)public static double add(int n1,double n2)
//方法名相同,参数顺序不同,构成重载。复制代码

//示例:只有返回值不同不构成方法的重载
public static int add(int n1, int n2)public static double add(int n1, int n2)
//只有返回值不同,不构成重载。
public static int add(int n1, int n2)public static int add(int num1,int num2)
//只有参数名称不同,不构成重载。复制代码

Object 클래스의 기본 특성

Object 클래스는 자바의 모든 클래스를위한 기초 클래스이다, 모든 Java 객체는 속성과 개체 클래스의 방법이있다. 자바는 단지 부모를 상속 할 수있는 서브 클래스가, 다음 부모 클래스는 클래스에서 가장 급진적 인 중 하나를 제공하는 Java 클래스 조직의 편의를 위해, 또한 하나의 부모가있는 경우에만 단일 상속을 지원, 모든 클래스에 해당하는이 출신 클래스는 Object 클래스이며, 상속. 지정되지 부모 클래스는 클래스 선언에 키워드를 확장하는 경우, 디폴트는 Object 클래스를 상속합니다.

여기에서이다 해시 코드가 무엇을 , 뒷면이 포함됩니다.

프로그램이 실행되면, 이러한 개체의 주소를 찾을 필요가 때 실행되는 가상 머신의 메모리 할당에있는 개체를 많이있을 수 있습니다, 어떤 위치에있는 각 개체의 기록과 자바 가상 머신 테이블, 이 테이블은 일반적으로 각 개체가 고유의 해시 코드를 가진 데이터 컨텐츠 및 데이터 저장 주소 사이의 매핑 관계를 구현, 기록을 코딩 해시를 사용합니다. 그러나 자바 그 자체의 실현은 해시 코딩 약간의 문제, 그것은, 충돌의 원인이 두 개체 다른 콘텐츠가 될 수 있지만, 모두 같은, 다른 개체가 시간을 코딩 해시를 계산이다의 해시 인코딩 할 수는 소위입니다 해시 충돌.

Object 클래스의 방법

문자열 및 연결의 또 다른 유형이 다른 유형이 자동으로 문자열로 변환 할 때 문자열은 연결되어 있습니다. 참조 유형은 어떻게 할 경우 문자열로 이중 기본 int 데이터 형식, 플로트, 디지털 그들의 전환에 따라, 비교적 간단하다? 학생 S1 = 새로운 학생, 문자열 S1 플러스이, 당신은 S1이 참조 형식이기 때문에, 문자열 P이를 변환하는 방법을 모르겠어요. 이 시간 toString 메소드 유용합니다.

//toString方法:该方法在打印对象时被调用,将对象信息变为字符串返回,默认输出对象地址
//toString方法源码:
public String toString() {
  return getClass().getName() + "@" + Interger.toHexString(hashCode());
  //默认会返回"类名+@+16进制的hashcode"。
  //在打印或者用字符串连接对象时,会自动调用该对象的toString()方法。
}


//示例:toString方法未重载之前
class Person {
    int age;
    String name;
public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p.age = 18;
        p.name = "芮耳朵";
        //自动调用了toString()方法,简写。
        System.out.println(p);
        //不简写
        System.out.println(p.toString());
      
   }
}
/*运行结果:Person@2a84aee7
           Person@2a84aee7 */
---------------------------------------------------
//示例:toString重载之后
class Person {
    int age;
    String name;
    @Override
    public String toString() {
        return name+",年龄:"+age;
    }
}
public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p.age = 18;
        p.name = "芮耳朵";
        System.out.println(p);
        System.out.println(p.toString());

    }
}
/*运行结果:芮耳朵,年龄:18
           芮耳朵,年龄:18 */复制代码

슈퍼 키워드

Java 클래스에서 새 개체가 시간 때, 객체는 객체 자체에이 기준점이의 참조를해야합니다. 새로운 객체가 클래스 객체 중 아이 인 경우,이 슈퍼 부모 내에서 현재 객체에 대한 슈퍼 기준점이 하위 클래스가있다. 이 프로그램에 해당, 우리는 객체 자신을 가리 키도록이를 사용, 상위 클래스 / 기본 클래스 / 슈퍼 클래스 내에서 현재의 서브 클래스 객체를 참조하는 슈퍼를 사용합니다.

//示例
class FatherClass {
  public int age;
  public void f() {
      age = 60;
      System.out.println("父类的年龄=" + age);
    }
}
class ChildClass extends FatherClass {
  //子类除了继承父类所具有的age属性外,又声明一个,此时的子类拥有两个age属性。
  public int age;
  //在子类ChildClass里面重写了由父类继承下来的f()方法的方法体。
  public void f() {
    super.f();
    //这里的super作为父类对象的引用对象用来调用父类对象里面的f()方法
    //打印输出语句  
    age = 20;//这个value是子类自己定义的age,不是从父类继承下来的那个age
    System.out.println("子类的年龄=" + age);
    //打印出来的是子类自定义的age值,值为20。
    System.out.println(age);
    System.out.println(super.age);
    }
}
复制代码

//测试类
public class Test {
    public static void main(String[] args) {
        ChildClass cc = new ChildClass();
        cc.f();
    }
}
/* 父类的年龄=60
   子类的年龄=20
   20
   60 */复制代码

꾸러미

포장은 내부 구현 객체를 숨길 수 있습니다, 즉, 개체의 속성과 메서드는 하나의 전체로 포장, 우리는 전화, 내부 개선이 외부 호출에 영향을 미치지 않습니다 방법을 알고만큼 호출 할 때. 우리는 원격 제어를 사용하는 것처럼, 당신은 단지 라인에서 작동하는 방법을 알아야 리모콘의 내부 구조를 필요가 없다.

왜 포장?

  • 그런 우리가 프로그램의 연령의 개인 재산을 가지고 있고, 외부 세계에 속성을 설정하는 설정 방법을 사용하는 경우 외부는, get 및 set 메소드를 제공 할 때와 외부의 문제, 코드와 데이터의 유형에 대한 보안 무작위 접근을 개선하고 수정하기 위해 만약 이와 같이, 통상의 연령 제한 값을 결정하는 방법으로 설정 될 수있는 시간 값을 임의로 지정 될 수 없다.
  • 다양한 방법으로 포장과 같은 코드의 재사용을 용이하게하기 위해, 아니 모든 방법은 세부에서 반복, 전화를 무료로 좋은 패키지가, 당신은 코드의 양을 줄이기 위해 호출 할 필요가 유일한 것, 그것은 간단한 것 같다.

캡슐화를 달성하기 위해

자바는 세부 사항, 노출에 필요한 사항의 세부 사항을 캡슐화 할 필요가 액세스 지정을 제어하는 데 사용됩니다. 네 개의 액세스 제어, 즉이 있습니다 개인, 기본, 보호, 공공 , 우리함으로써 안전성을 향상, 최소한에 액세스 할 수 있도록 가능한 한 많이 사용할 필요는.

개인은 : 개인 대표, 액세스의 가장 엄격한 수준의, 당신은 객체를하는 사용, 단지 자신의 클래스를 액세스 할 수있는 변수와 메소드를 . 개인 수정 변수은 외부 공용 클래스의 get 메소드에 액세스 할 수 있습니다.

public class Person {
  private int age;
  public int getAge() {  //通过get方法来访问private修饰的变量。
    return this.age;  
 }
  public void setAge(int age) {
    this.age = age;  //通过set方法来修改private修饰的变量。
  }
}复制代码

기본 : 그 어떤 수정없이 쓸 수있는 아무것도, 기본값을 나타냅니다, 동일한 패키지에 액세스 할 수 있습니다 만, 클래스, 사용하여 개체는 클래스, 인터페이스, 변수와 메소드 .

//示例
int i = 1;  //没有任何修饰符修饰int。
boolean isTall() {  //没有任何修饰符修饰方法boolean。
  return true;
  }复制代码

보호 : 클래스가 동일한 패키지와 서브 클래스 액세스 및 다른 모든 패키지가 될 수 있습니다 나타냅니다, 그래서 클래스가 이러한 방법 및 관련 변수를 사용하지 않는 보호합니다. 사용 객체는 변수와 메소드 . 인터페이스 부재 변수와 인터페이스하는 방법은 보호 선언 될 수 없다.

//示例
class Person {
  protected boolean isTall() {
    return true;
  }
}

class Player extends Person {
  protected boolean isTall() {
    //此处省略...重写父类的isTall()方法。
  }
}

//如果把isTall()方法声明为private,那么除了Person之外的类将不能访问。
//如果把isTall()方法声明为public,那么所有的类都可以访问该方法。
//如果只想让isTall()方法对其所在类的子类可见,则将该方法声明为protected。复制代码

공공 : 오브젝트 사용할 패키지의 모든 항목에 액세스 할 수있는 모든 종류이다 나타내는 클래스, 인터페이스 변수 방법 .

//示例
//Java程序的main()方法必须设置成public,否则Java解释器将不能运行该类。
public static void main(String[] args) {
  //代码...
  }复制代码

액세스 제어 및 상속 규칙

부모 클래스의 서브 클래스에 선언 된 공공 방법은 공개해야합니다.

서브 클래스에서 protected 또는 public으로 선언 부모 클래스에 선언 된 보호 방법 중 하나를 선언, 개인이 될 수 없습니다.

부모 클래스에 선언 전용 메서드는 상속 될 수 없습니다.

비 액세스 한정자

정적 수정

정적 변수 : 또한 클래스 변수로 알려진 정적 변수를 선언하는 정적 키워드 멤버 변수는 관계없이 클래스 인스턴스의 얼마나 많은 개체, 공용 변수 이런 종류의, 그것은 정적에 의해, 그래서 정적 변수의 복사본입니다 기준값은 그 특성을 수정 객체의 속성 값이 수정의 결과이다. 지역 변수가 정적 변수로 선언 할 수 없습니다 .

정적 방법 : 정적 메서드로 선언 된 정적 방법, 당신은 직접 액세스의 이름을 입력 할 수 있습니다, 비 정적 방법은 속성 또는 메서드 정적 선언 호출 할 수 있습니다 비 정적 선언의 속성 또는 메서드를 호출 할 수 없습니다 방법 정적 선언 , 비 정적 변수 때문에 객체 클래스 이름이 생성되지 않은 경우 당신은 속성의 비 정적 메소드를 호출 정적 정적 메소드를 사용하면 오브젝트가 작성되지 않았습니다 그래서 때, 호출 할 수있는 새 개체 초기화 및 방법의 정적 유형에 의해 생성 또는 방법은 논리 순서는 정적 메소드 내의 비 정적 부재를 액세스 할 수 있으므로 실패하고있다.

최종 수정

클래스의 최종 선언이 상속 될 수 없습니다 사용 , 더 클래스는 어떤 특성이 최종 상속 할 수 없습니다. 콘텐츠의 방법의 최종 선언 재기록이 불가 오버라이드 (상위 클래스 및 서브 클래스는 동일한 방법 이름 및 파라미터를 갖는다), 그러나 과부하 될 수 과부하 (동일한 메소드의 이름, 다른 매개 변수, 즉, 가장 일반적으로 사용되는 방법은 과부하 생성자) . 일정 변수 최종 선언을 수정할 수 없습니다 변수의 최종 선언을 사용하는 경우, 모두 대문자가 필요합니다. 프로그램의 변수가 공공 정적 최종 선언을 사용하는 경우, 변수는 전역 상수가 될 것입니다.

            그림 : 방법의 최종 수정 재정의 할 수 없습니다

            그림 : 방법의 최종 수정 재정의 할 수 없습니다

추상적 수정

초록 : 사용 추상적 수정 방법은 어떤 방법 본체 만 문이 없습니다 . a의 정의를 "표준" 구현을 제공하는 추상 메소드를 제공해야하는 서브 클래스를 알려주는 것이다.

추상 클래스 : 클래스의 추상 메소드는 추상 클래스입니다 포함되어 있습니다 . (서브 클래스가 추상 클래스도 아닌 경우) 사양에 의해 서브 클래스가 추상 메소드의 모든 클래스의 추상 상위 클래스를 상속 정의 된 추상 방법을 구현해야합니다. 추상 메소드 선언은 예를 들어, 세미콜론으로 끝나야 : 추상적 무효 연구 ();

//示例
abstract class Person {
  abstract public void study();  //抽象方法
}
class Student extends Person {
  //子类必须实现父类的抽象方法,否则编译出错。
  public void study() {
    System.out.println("每天进步一点点!");
  }
}
//测试抽象类
public class Test{
  public static void main(String[] args) {
    Student s1 = new Student();
    s1.study();
  }
}复制代码

추상 클래스는 유도 요소를 사용

추상 클래스에서만 상속 할 수 있습니다.

추상 메소드는 선언하지 구현해야하는 것입니다.

상기 방법은 추상 클래스는 추상 클래스로 정의 될 수를 포함한다.

추상 메소드 추상 클래스는 개인 성명을 사용하지 마십시오.

추상 클래스와 추상 메소드는 추상적 인 키워드를 사용하여 선언해야합니다.

추상 클래스는 즉, 새로운 추상 클래스를 인스턴스화 할 수 없습니다, 인스턴스화 할 수 없습니다.

추상 메소드는 모든 추상 메소드는 추상 클래스가 오버라이드 (override) 할 필요가 있습니다, 이불 클래스, 하위 클래스는 단지 추상 클래스하지 않습니다 달성해야합니다.

다형성

다형성은 다른 동작을 가질 수도 다르기 때문에 목적에 동일한 메소드 호출을 의미한다. 실제 생활에서, 같은 방법은 특정 구현은 완전히 다른 것입니다. 예를 들면 다음과 같은 사람들 "운동"접근, 쑨양의 수영, 농구 말론 탁구를 재생, 야오밍입니다 호출하는 것입니다. 운전 중 뭔가 다른 행동이있을 수 있습니다.

다형성 세 가지 필요 조건이 존재합니다 :

1. 서브 클래스는 부모 클래스를 상속

2. 서브 클래스 재정의 상속 방법

3. 이러한 상위 p = 새로운 자식으로서 상위 클래스의 하위 클래스 객체에 대한 참조 ();

여러 방법은 상태 모드를 호출 할 때, 상위 클래스가 아니라면, 개시된 방법은 다음의 새로운 서브 클래스 정의를 컴파일 오류되는 프로세스는 먼저 존재하는지, 그렇다면 동안 다시 서브 같은 이름의 메소드를 호출 구현은 다형성 부모 아니다.

//父类
public class Athlete {
  int age = 10;
  public void exercise() {
    System.out.println("运动员锻炼");
  }
}
//子类
class XunYang extends Athlete {
  int age = 20;
  public void exercise() {
    System.out.println("孙杨游泳锻炼");
  }
  public void run() {
    System.out.println("孙杨正在跑步");
  }
}

//子类觉得父类方法不够好,重写一个!
class YaoMing extends Athlete {
  int age = 30;
  public void excercise() {
    System.out.println("姚明打篮球锻炼");
 }
}

class MaLong extends Athlete {
  int age = 40;
  public void exercise() {
    System.out.println("马龙打乒乓球锻炼");
  }
}复制代码

//测试类1
public class Test {
    public static void main(String[] args) {
        Athlete a = new XunYang();
        a.excercise();
        // a.run(); 编译报错,需要向下强制转型
        System.out.println("年龄是" + a.age);
    }
}
/* 运行结果:孙杨游泳锻炼
            年龄是10 */
复制代码

전체 Java 다형성 세 가지 조건이 a.exercise ()를 호출 실제로 운동의 서브 클래스이지만, 부모 클래스, 나이,하지만 a.run을 (a.age 전화)을 발견 할 수있는 경우하지 않습니다 컴파일합니다.

//测试类2
public class Test {
  public static void main(String[] args) {
    Athlete a1 = new XunYang();  //向上自动转型
    SportsExercise(a1);
    Athlete a2 = new YaoMing();
    SportsExercise(a2);
    Athlete a3 = new MaLong();
    SportsExercise(a3);
      
    //由于这里调用的是自己新的方法,是父类没有的方法。
    //a1.run();编译报错,这里必须要强制向下转型。
    XunYang ath = (XunYang) a1;  
    ath.run();
    System.out.println(("年龄是" + a1.age));  }

  //这里就可以看做是同一个方法“锻炼”,产生多态。
  //如果没有多态,我们这里需要写很多重载的方法
  //每增加一个运动员,就需要重载一个锻炼的方法,非常麻烦
  /* static void Athlete(XunYang x) {
       x.exercise;     
     }
     static void Athlete(YaoMing y) {
       y.exercise;
     }
     ... */
     
    static void SportsExercise(Athlete a) {
    a.exercise();
    }
}
/* 运行结果:孙杨游泳锻炼
            姚明打篮球锻炼
            马龙打乒乓球锻炼  
            孙杨正在跑步
            年龄是10  */复制代码

상기 상위 클래스를 매개 변수로하는 방법의 가장 일반적인 사용 다형성 하나이고, 인자는 서브 클래스 객체가 객체의 다른 서브 클래스의 동작에 의해 다양한 방식으로 달성 될 수 수있다.


추천

출처juejin.im/post/5d4bc40651882523942f6b17