Java---第 6 章
1パッケージ(カプセル化)
パッケージの紹介
カプセル化とは何ですか?
カプセル化は、クラスの一部のプロパティとメソッドを非表示にすることであり、外部プログラムによる直接アクセスを許可しません。クラスで定義されたプロパティとメソッドには、クラスによって公開されているメソッドを介してのみアクセスできます。カプセル化は、3 つの主要なうちの 1 つです。オブジェクト指向の特徴。
カプセル化を使用するにはどうすればよいですか?
例:
Person クラスを作成する
public class Person {
public String name;//姓名
public int age;//年龄
public String secret;//秘密
public Person(String name,int age,String secret){
this.name=name;
this.age=age;
this.secret=secret;
}
}
属性の可視性を変更する: クラスで定義されているすべての属性をプライベート変更に変更します。
public class Person {
private String name;//姓名
private int age;//年龄
private String secret;//秘密
public Person(String name,int age,String secret){
this.name=name;
this.age=age;
this.secret=secret;
}
}
年齢の値を直接変更すると、エラーが報告されます。
public class PersonTest {
public static void main(String[] args){
Person p1 = new Person("刘德华",54,"双重人格");
p1.age=30;//报错
}
}
パブリックの getter/setter メソッドを作成する: プロパティ値の読み取り/変更用
public class Person {
private String name;//姓名
private int age;//年龄
private String secret;//秘密
public Person(String name,int age,String secret) {
this.name=name;
this.age=age;
this.secret=secret;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
}
public class PersonTest {
public static void main(String[] args){
Person p1 = new Person("刘德华",54,"双重人格");
p1.setName("伍六七");
String name = p1.getName();
}
}
getter/setter メソッドに制御ステートメントを追加します。属性値の有効性を検証するために使用されます。
クラス内で、対応する属性に検証ステートメントを追加します。
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 0) {
System.out.println("年龄不合法,必须大于0");
} else {
this.age = age;
}
}
メソッド内で
public class PersonTest {
public static void main(String[] args){
Person p1 = new Person("刘德华",54,"双重人格");
p1.setAge(-1);
//输出
//年龄不合法,必须大于0
}
}
なぜカプセル化を使用するのでしょうか?
- カプセル化によりコードの再利用性が向上します。
カプセル化により外部アクセス用のパブリック メソッドが提供され、メソッドを再利用できるため、カプセル化によりコードの再利用性が向上します。 - カプセル化によりコードの保守性が向上します。
コードを変更する場合、コードの一部のみを変更する必要がありますが、他のコードには影響しません。
例: 年齢は設計上で負の数の場合にのみ考慮されますが、実際の生活では考慮されません。人の年齢は通常 200 歳を超えないため、検証レイヤーを追加する必要があります。
public void setAge(int age) {
if (age < 0 || age > 200) {
System.out.println("年龄不合法,必须大于0并且小于200");
} else {
this.age = age;
}
}
- カプセル化により、クラスの特定の実装の詳細が隠蔽され、コード実装ロジックが保護されます。
2パック(パッケージ)
パッケージの紹介
パッケージとは何ですか?
パッケージは Java の専門用語であり、パッケージの本質はフォルダーです。
なぜパッケージを使用するのでしょうか?
- パッケージは、作成したクラスを分類できます。
- 名前の競合を防ぐことができる
- アクセス制御
パッケージを作成するにはどうすればよいですか?
文法:
package 包名;
このうちcom、ly、chat11はそれぞれフォルダです
パッケージ名の命名規則は次のとおりです。
- パッケージ名は通常、小文字と数字で構成され、各パッケージは「.」で区切られます。つまり、「.」が出現するすべてがパッケージです。
- 通常、パッケージ名には接頭辞が含まれます。
- 通常、個人/組織はorg.nameです。
- 会社は通常、com. 会社名の略称またはcn. 会社名の略称です。
- クラスにパッケージ定義がある場合、このクラスの有効なコードの最初の行はパッケージ定義である必要があります。
パッケージをインポートするにはどうすればよいですか?
同じパッケージ内にないクラスを使用するには、 import キーワードを使用して、Java プログラムにこのクラス構文を導入する必要があります
。
import 包名.类名;
package com.ly.chat11;
//类的全限定名:包名+'.'+类名
import java.util.Scanner;//告诉JVM,到Java.util包下去找一个名为Scanner的类
public class User {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
}
}
パッケージをインポートする理由
JVM は現在のパッケージ内のすべてのクラスしか認識できないため、現在のパッケージ以外のパッケージのクラスを使用したい場合は、どのパッケージ内のどのクラスを使用するかを JVM に指示する必要があります。
クラスは、異なるパッケージにある同じ名前を持つ 2 つのクラスを同時に参照します。これらは完全なクラス名 (クラスの完全修飾名) によって区別する必要があります。
よく使用されるパッケージの説明:
Java.lang 包
Java 言語の開発パッケージに属しており、このパッケージ内のクラスはパッケージをインポートせずに直接使用できます。JVM は、
よく使用する System、String、Math などを自動的に導入するためです。
Java.util 包
これは、Java によって提供されるいくつかの使用クラスおよびツール クラスに属します。
例: 私たちがよく使うスキャナー
トリプルアクセス修飾子
アクセス修飾子の概要
コンセプト:
アクセス修飾子は、アクセス許可を制御する修飾子シンボルです。
クラスのアクセス修飾子:
クラスのアクセス修飾子は次の 2 種類のみです。
- パブリック修飾子
- デフォルトの修飾子 (デフォルトは修飾子なし)
public 修飾子は、クラスがパブリックにアクセス可能であることを示すためにクラスを変更します。
デフォルトの修飾子はクラスを変更し、そのクラスが同じパッケージ内でのみアクセスできることを示します
クラス メンバーのアクセス修飾子:
クラス メンバーには、メンバー プロパティとメンバー メソッドが含まれます。
クラス メンバーのアクセス修飾子は、言い換えれば、メンバー プロパティとメンバー メソッドのアクセス修飾子です。
4つのスタティックメモリ
static 修飾子の適用範囲:
static 修飾子は、クラス内に定義されているメンバー変数、メンバー メソッド、コード ブロック、および内部クラスを変更するためにのみ使用できます (内部クラスについては特別な章で説明しています)。
静的に変更されたメンバー変数:
静的に変更されたメンバー変数が呼び出されます。クラス変数。クラス全員で共有
国の初期値が「中国」、変更後は「日本」の場合、呼び出しの値は「日本」になります。これは
メンバー変数ではないため、メンバーによって変更されません。
クラス変数がパブリックの場合は、次のように使用できます。クラス名.変数名変数への直接アクセス
静的に変更されたコード ブロック:
静的に変更されたコード ブロックは静的コード ブロックと呼ばれ、JVM が最初にクラスを記録するときに実行されます。
したがって、静的コード ブロックは 1 回だけ実行でき、通常は一部のシステム設定シナリオで使用されます。
static {
}
五つの相続(相続)
継承の概要
概念:
継承の概念はシンプルですが強力です。新しいクラスを作成する必要があり、必要なコードを含むクラスがすでに存在する場合、既存のクラスから新しいクラスを派生できます。こうすることで、既存のクラスのフィールドとメソッドを自分で作成 (デバッグ) せずに再利用できます。
サブクラスは親クラスからすべてのメンバー (フィールド、メソッド、およびネストされたクラス) を継承します。コンストラクターはメンバーではないため、サブクラスに継承されません。ですが、スーパークラスのコンストラクターはサブクラスから呼び出すことができます。
クラスから派生したクラスはサブクラス (派生クラス、拡張クラス、またはサブクラスの場合もあります) と呼ばれ、サブクラスから派生したクラスはスーパークラス(基本クラスまたは親クラスとも呼ばれます)と呼ばれます。
継承はオブジェクト指向の 3 つの主要な特徴の 1 つでもあります。
継承をどのように使用するか?
文法:
publis class 子类名 extends 父类名{
}
例:
public class Person{
public String name;
public String sex;
public int age;
public void eat(){
System.out.println("吃饭");
}
}
public class PersonTest extends Person{
public void show(){
System.out.println(name);
//本类中未定义name变量,但却可以使用,说明name变量是从父类中继承过来的
}
}
継承されたプロパティとメソッド:
サブクラスがどのようなパッケージに含まれているかに関係なく、サブクラスは親クラスのすべての public および protected メンバー (フィールドおよびメソッドを含む) を継承します。サブクラスと親クラスが同じパッケージ内にある場合、サブクラスは親クラスのパッケージで保護されたメンバーも継承します。
サブクラスは親クラスで定義されたプライベート メンバーを継承しませんが、親クラスにフィールドへのパブリック アクセスまたは保護されたアクセスを提供するメソッドがある場合、これらのメソッドをサブクラスでも使用できます。
繰り返しのコード:
public class Person{
public String name;
public String sex;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(){
System.out.println("吃饭");
}
}
医師専用のクラス:
public class Doctor extends Person{
private String professional;
public String getProfessional() {
return professional;
}
public void setProfessional(String professional) {
this.professional = professional;
}
public void cure(){
System.out.println("治病");
}
}
テスト、オブジェクトの作成:
public class PersonTest{
public static void main(String[] args) {
Doctor d =new Doctor();
d.setName("Miss");
d.setSex("女");
d.setAge(19);
d.setProfessional("临床");
//优化之后
Person p1 = new Doctor();
p1.setName("Miss");
p1.setSex("女");
p1.setAge(19);
p1.setProfessional("临床");//报错,因为该类不在Person里
//但是我们可以使用强制类型转换
((Doctor)p1).setProfessional("临床");
}
}
サブクラスと親クラスの間の関係は is-a 関係です。つまり、
オブジェクトがその親クラス参照に割り当てられている場合、この時点でオブジェクトの一意のメソッドを呼び出したい場合は、それをキャストする必要があります。
6 つのメソッドの書き換え (オーバーライド)
メソッドのオーバーライドの概要
サブクラスのメンバー メソッドは、親クラスのメンバー メソッドと同じシグネチャ(メソッド名にパラメーターの数と型を加えたもの) を持ち、戻り値の型のインスタンス メソッドは親クラスのメソッドをオーバーライドします。
メソッドオーバーライドの使用方法:
サブクラスがメソッドをオーバーライドできる機能により、クラスは「十分に近い」動作をする親クラスから継承し、必要に応じて動作を変更できます。オーバーライドするメソッドは、オーバーライドされるメソッドと同じ名前、番号、パラメーターの型を持ちます。の戻り型が同じである場合、オーバーライドするメソッドは、オーバーライドするメソッドによって返される型のサブタイプを返すこともできます。このサブタイプは、共変戻り型と呼ばれます。
例:
public Number getScore(){
return 0;
}
サブクラスが親クラスのメソッドをオーバーライドする場合、戻り値の型は親クラスのメソッドの戻り値の型のサブクラスにすることができます。
メソッドをオーバーライドする場合、アクセス修飾子のレベルを下げることはできません
public Integer getScore(){
return 90;
}
メソッドをオーバーライドするときは、次の使用が必要になる場合があります。@オーバーライド注釈を付けます。これは、親クラスのメソッドをオーバーライドするつもりであることをコンパイラーに示します。何らかの理由で、コンパイラが親クラスにメソッドが存在しないことを検出すると、エラーが生成されます。
これまでに学習した数値には、byte short int long float double type
と、それに対応する数値が含まれます。数値のサブクラス:バイト Short Integer Long Float Double
7つのスーパーキーワード
コンセプト:
サブクラスのコンストラクターが親クラスのコンストラクターを明示的に呼び出さない場合、Java コンパイラーは親クラスの引数のない構造への呼び出しを自動的に挿入します。スーパークラスに引数なしのコンストラクターがない場合は、コンパイル時エラーが発生します。
オブジェクト クラスには引数のないコンストラクターがあるため、オブジェクト クラスが唯一の親クラスである場合、これは問題ありません。
例 1: サブクラスも親クラスもコンストラクターを定義していません
。親クラス:
public class Person{
public String name;
public Person(){
super();
}
public Number getScore(){
return 0;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
サブクラス:
public class Doctor extends Person{
private String professional;
//如果一个类中没有定义构造方法,那么编译器将会给该类插入一个无参构造方法
public Doctor(){
super();//如果子类构造方法中没有明显调用父类的构造方法,那么编译器会
//自动插入一个父类的无参构造的调用
}
public String getProfessional() {
return professional;
}
public void setProfessional(String professional) {
this.professional = professional;
}
public void cure(){
System.out.println("治病");
}
}
例 2: サブクラスにはコンストラクターが定義されていますが、親クラスにはコンストラクターが定義されていません。
親クラス:
public class Person{
public String name;
// public Person(){
// super();
// }
public Number getScore(){
return 0;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
サブクラス:
public class Doctor extends Person{
private String professional;
public Doctor(){
super();
}
public Doctor(String name){
super();
this.name = name;
}
public String getProfessional() {
return professional;
}
public void setProfessional(String professional) {
this.professional = professional;
}
public void cure(){
System.out.println("治病");
}
}
例 3: サブクラスと親クラスの両方にコンストラクターが定義されています 親クラス
:
public class Person{
public String name;
public Person(String name,String sex){
this.name = name;
this.sex = sex;
}
public Number getScore(){
return 0;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
サブクラス:
public class Doctor extends Person{
private String professional;
public Doctor(String name,String sex){
super(name,sex);
//如果父类中定义了带参构造,并且没有定义无参构造,
//那么必须在子类的带参构造方法中显示的调用父类的带参构造
}
public String getProfessional() {
return professional;
}
public void setProfessional(String professional) {
this.professional = professional;
}
public void cure(){
System.out.println("治病");
}
}
super を使用して親クラスのコンストラクターを呼び出す場合、それがコンストラクターの最初のステートメントである必要があります
public class Doctor extends Person{
private String professional;
public Doctor(String name,String sex){
//报错,不是第一条语句
System.out.println("abc);
super(name,sex);
}
}
メソッドが親クラスのメソッドの 1 つをオーバーライドする場合、キーワードsuperを使用して、親クラスでオーバーライドされたメソッドを呼び出すことができます。super
を使用して隠しフィールドを参照することもできます(ただし、隠しフィールドは推奨されません)。
隠しフィールド:
親クラス:
public class Person{
protected String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
サブクラス:
public class Doctor extends Person{
private String name;
public Doctor(String name){
this.name = name;
}
}
public class PersonTest{
public static void main(String[] args) {
Doctor d = new Doctor("Mis");
System.out.println(d.getName());
//null
}
}
対応する名前を取得したい場合は、メソッドをオーバーライドできます。
サブクラス:
public class Doctor extends Person{
private String name;
public Doctor(String name){
this.name = name;
}
@Override
public String getName() {
return name;
}
}
親クラスの変数とサブクラスの変数の両方を取得したい場合はどうすればよいでしょうか?
サブクラス:
public class Doctor extends Person{
private String name;
public Doctor(String name){
this.name = name;
}
public void show(){
System.out.println(this.name);//访问本类中定义的name变量
System.out.println(super.name);//访问父类中定义的变量
}
}
サブクラスと親クラスが同じメンバー変数を持たない場合は、this と super を使用して、この時点で親クラスのメンバー変数を呼び出すことができます
。
public class PersonTest{
public static void main(String[] args) {
Doctor d = new Doctor("Mis");
System.out.println(d.getName());
d.show();
}
}
すべてはオブジェクトです
親を持たない Object を除いて、すべてのクラスは 1 つだけの直接の親を持ちます (単一継承)。他に明示的なスーパークラスが存在しない場合、すべてのクラスは暗黙的に Object のサブクラスになります。
クラスは別のクラスから派生することができ、そのクラスは別のクラスから派生することができ、その後も同様に、最終的に最上位のクラス Object から派生できます。このようなクラスは、継承チェーン内のすべてのクラスの子孫であり、Object にまで拡張されると言われます。
すべてのクラスは Object のサブクラスであるため、オブジェクトを作成するときは、Object クラスで引数なしのコンストラクターを呼び出す必要があり、Object 自体がオブジェクトを表すため、すべてのオブジェクトが作成されます。
最終修飾子
適用範囲:
Final 修飾子はクラス、変数、メソッドに対して使用する必要があります。
最終変更クラス:
クラスの一部またはすべてのメソッドを Final として宣言できます。メソッド宣言で Final キーワードを使用すると、そのメソッドがサブクラスによってオーバーライドできないことを示します。
オブジェクト クラスはまさにそれを行います。そのメソッドの多くは最終的なものです。
クラスが Final によって変更された場合、そのクラスは Final であることを意味するため、継承はクラスを拡張することであるため、このクラスは継承できません。
public final class Person{
public void show(){
System.out.println("这里是最终类里的方法");
}
}
サブクラスはエラーを直接報告します
public class Doctor extends Person{
}
最終的な修正方法
注記:クラス全体を Final として宣言することもできますが、final として宣言されたクラスをサブクラス化 (継承) することはできません。
例: これは、 String クラスなどの不変クラスを作成する場合に特に便利です。
public class Person{
public final void show(){
System.out.println("这是一个最终方法,不能被重写");
}
}
エラーを直接報告する
public class Doctor extends Person{
public void show(){
}
}
最終修飾子変数
Final が変数を変更する場合、オブジェクトの構築時に変数を初期化する必要があります。
Final によって変更された変数は定数と呼ばれます
public class Doctor extends Person{
private final int number;
public Doctor(){
this.number = 10;
}
}