Java カプセル化、継承、多態性のメモ
1パッケージ
1. パッケージの命名規則
(1) 数字、文字、アンダースコア、ドットのみを含めることができます。
(2) 数字で始めることはできません。
(3) キーワードや予約語は使用できません
例えば:
Demon.class.exec1 //エラークラスはキーワードです
demo.12a //エラー、数字で始めてください
demo.ab12.oa // 对
命名規則の例:
通常は小文字 + 小さなドット(通常は com.会社名.プロジェクト名.ビジネスモジュール名)
例えば:
com.hspedu.oa.model;
com.hspedu.oa.コントローラー;
例:
com.sina.crm.user//user モジュール
com.sina.crm.order//オーダーモジュール
com.sina.crm.utils //ツールクラス
2. よく使われるパッケージ
パッケージには多くのクラスが含まれており、Java で一般的に使用されるパッケージは次のとおりです。
java.lang.* //lang パッケージは基本パッケージであり、デフォルトでインポートされるため、再度インポートする必要はありません
java.util.* //util パッケージ、システムによって提供されるツールキット、ツール クラス、スキャナーを使用
java.net.* //ネットワークパッケージ、Web開発
java.awt.* // Javaインターフェース開発、GUIを行います
3. パッケージ導入時の注意点
クラスには最大でも 1 つのパッケージがあります
package の機能は、現在のクラスが配置されているパッケージを宣言することです。パッケージはクラスの先頭に配置する必要があります。1 つのクラスには最大 1 つのパッケージがあります。
2. アクセス修飾子
1. 基本的な紹介
Java では、メソッドと属性 (メンバ変数) のアクセス権 (範囲) を制御するために 4 種類のアクセス制御修飾子シンボルが提供されています。
1. 公開レベル:公開付きで修正、公開
2. 保護レベル: protected で変更され、同じパッケージ内のサブクラスおよびクラスに対してオープン
3. デフォルト レベル: 修飾子なし、同じパッケージ内のクラスにオープン
4. プライベートレベル: プライベートで装飾され、クラス自体のみがアクセスでき、公開されません。
3. オブジェクト指向プログラミングの 3 つの特徴: 継承、カプセル化、ポリモーフィズム
1. カプセル化
1.1 パッケージの定義
カプセル化(カプセル化)とは、抽象化されたデータ[属性]とそのデータに対する操作[メソッド]をまとめてカプセル化することで、データは内部で保護され、プログラムの他の部分は許可された操作[メソッド]を通じてのみデータを操作できるようになります。 。
1.2 カプセル化実装ステップの 3 部作
1)属性をプライベート化【属性を直接変更することはできません】
2) プロパティを判断して割り当てるためのパブリック (パブリック) セットメソッドを提供する
public void setXxx(类型参数名){
//set方法用来设置或者修改属性值
//加入数据验证的业务逻辑属性=参数名;
}
3) 属性の値を取得するためのパブリック get メソッドを提供します。
public XX getXxx(){
//权限判断
return xx;
}
1.3 クイックスタートケースのパッケージ化
ケースその 1:
人の年齢、給与、その他のプライバシーを自由にチェックしたり、設定された年齢を合理的に検証したりすることは不可能です。
年齢が妥当な場合は設定します。そうでない場合は、デフォルトの「年齢は 1 ~ 120 である必要があり、年齢と給与を直接確認することはできません。名前の長さは 2 ~ 6 です」
package com.hspedu.encap;
//不能随便查看人的年龄,工资等隐私,并对设置的年龄进行合理的验证。年龄合理就设置,否则给默认
//年龄必须在1-120,年龄,工资不能直接查看,name的长度在2-6之间
public class Encapsulation {
public static void main(String[] args) {
Person person = new Person();
person.name="li";
person.setAge(10);
person.setSalary(10000);
System.out.println(person.info());
}
}
class Person{
public String name;
private int age;
private double salary;
public void setName(String name){
if(name.length() >=2 && name.length() <=10)
this.name = name;
System.out.println("不合法");
}
public void setAge(int age) {
if(age < 1 || age > 120)
System.out.println("年龄不符合条件");
this.age = age;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getName(){
return name ;
}
public int getAge() {
return age;
}
public double getSalary() {
return salary;
}
//写一个方法返回字符串
public String info(){
return "信息为 name="+name+"age="+age+"salary="+salary;
}
}
ケース 2:
プログラムを作成し、その中に Account クラスと AccountTest クラスの 2 つのクラスを定義し、Java のカプセル化を体験します。
1. Account クラスには属性が必要です: 名前 (2 桁、3 桁、または 4 桁の長さ)、残高 (20 桁以上である必要があります)、パスワード (6 桁である必要があります)。満たされていない場合は、プロンプト メッセージが表示されます。 、デフォルト値が与えられます
2. setXxx メソッドを使用して、アカウントのプロパティに値を割り当てます。
3. AccountTest でテストする
プロンプトの知識ポイント:
String name="";int len = name.length();
package com.hspedu.encap;
public class Account{
String name;
double salary;
String pass;
public Account() {
}
public Account(String name, double salary, String pass) {
this.name = name;
this.salary = salary;
this.pass = pass;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
public void setName(String name) {
if(name.length() == 2 || name.length() == 3 || name.length() == 4)
this.name = name;
}
public void setSalary(double salary) {
if(salary >= 20){
this.salary = salary;
}else {
this.salary = 0;
}
}
public void setPass(String pass) {
if(pass.length() == 6)
this.pass = pass;
else {
System.out.println("密码错误");
this.pass = "000000";
}
}
public String getPass() {
return pass;
}
public void showInfo(){
System.out.println("name =" + name + "salary =" + salary + "pwd =" + pass);
}
}
package com.hspedu.encap;
public class AccountTest {
public static void main(String[] args) {
Account account = new Account();
account.setName("ping");
account.setSalary(13);
account.setPass("123456");
account.showInfo();
}
}
2. 継承
1. 継承の基本的な概要と概略図
継承はコードの再利用を解決し、プログラミングを人間の思考に近づけることができます。複数のクラスが同じ属性 (変数) とメソッドを持つ場合、親クラス内でこれらのクラスから親クラスを抽象化できます。
これらと同じプロパティとメソッドがクラスで定義されており、すべてのサブクラスはこれらのプロパティとメソッドを再定義する必要はなく、extendsを通じて親クラスの継承を宣言するだけで済みます。
継承の模式図を描く
2. 継承の基本文法
class 子类 extends 父类{
}
1) サブクラスは、親クラスによって定義されたプロパティとメソッドを自動的に持ちます。
2) 親クラスは、スーパークラス、基本クラスとも呼ばれます。
3) サブクラスは派生クラスとも呼ばれます。
3. 理解に重点を置く
1. サブクラスはすべてのプロパティとメソッドを継承します。非プライベートのプロパティとメソッドにはサブクラスで直接アクセスできますが、プライベートのプロパティとメソッドにはサブクラスで直接アクセスできません。パブリック メソッドを介してアクセスする必要があります。
分割します
(1) サブクラスはすべてのプロパティとメソッドを継承します。非プライベートなプロパティとメソッドは、継承後に使用できない親クラスのプライベート メソッドを除き、サブクラス内で直接アクセスでき、メソッドとともに使用できます。
父親
package com.hspedu.extend_.improve;
//父类,是pupil和graduate的父类
public class Student {
//共有的属性
public String name;
private double score;
public int age;
//共有的方法
public void setScore(double score) {
this.score = score;
}
public void showInfo(){
System.out.println(age + "岁的" + name + "考试考了" + score);
}
}
サブクラス: 表示される特定の情報のみが異なると仮定すると、この情報はサブクラスに固有の情報となります
package com.hspedu.extend_.improve;
public class Pupil extends Student {
public void testInfo(){
System.out.println("小学生" + name + "正在考小学数学");
}
}
package com.hspedu.extend_.improve;
public class Graduate extends Student{
public void testInfo(){
System.out.println("大学生"+ name + "正在考大学数学");
}
}
テスト
package com.hspedu.extend_.improve;
public class Test {
public static void main(String[] args) {
Pupil pupil = new Pupil();
pupil.name="li";
pupil.age = 10;
pupil.setScore(100);
pupil.testInfo();
pupil.showInfo();
System.out.println("==============");
Graduate graduate = new Graduate();
graduate.name = "ping";
graduate.age = 20;
graduate.setScore(98);
graduate.testInfo();
graduate.showInfo();
}
}
(2) ただし、サブクラスではプライベート プロパティとメソッドに直接アクセスすることはできません。
今の年齢は共通属性
//如果把父类中年龄改成私有的
private int age;
//测试中的这一行代码会出错
pupil.age = 10;
(3) 上記問題の解決: パブリックメソッドによるアクセス
package com.hspedu.extend_;
public class Base {
//不同的属性
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
//n4是私有的,Sub无法直接拿到
private int n4 = 400;
//父类中提供了一个public的方法,返回了n4,通过这个方法,Sub类中就可以拿到n4的参数
public int getN4() {
return n4;
}
//无参构造器
public Base(){
System.out.println("父类的无参构造器Base()被调用....");
}
//不同的属性
public void Base1(){
System.out.println("Base1()...");
}
void Base02(){
System.out.println("Base2()...");
}
protected void Base03(){
System.out.println("Base03()...");
}
//在Sub中是无法获取的
private void Base4(){
System.out.println("Base4()....");
}
//可以通过这个方法来实现
public void callBase4(){
Base4();
}
}
テスト
package com.hspedu.extend_;
public class Sub extends Base{
public Sub(){
// super();//默认调用父类的无参构造器,写不写都会被调用
System.out.println("子类的无参构造器Sub()被调用...");
}
public void ok(){
System.out.println("n1:"+ n1+ "\t n2:" + n2 + "\t n3:" + n3);
//由于Base下的n4是私有的,因此无法直接拿到,但是可以将私有的属性通过共有的方法让继承后类中使用
System.out.println("n4:"+getN4());
Base1();
Base02();
Base03();
//Base4的方法是私有的无法拿到,但是可以通过共有的方法那它在传到当前位置来
//Base4();
//在Base中使用了公共方法将其传入
callBase4();
}
}
2. サブクラスは親クラスのコンストラクターを呼び出して、親クラスの初期化を完了する必要があります。
//尽管Sub类中的方法没有调用父类的无参构造器,但是也会显示父类无参构造器相关信息,然后显示子类的无参构造器相关信息
//上面代码的片段
public class Sub extends Base{
public Sub(){
// super();//默认调用父类的无参构造器,写不写都会被调用
System.out.println("子类的无参构造器Sub()被调用...");
}
public Sub(String name ){
System.out.println("子类有参构造器Sub(String name )被调用");
}
}
テスト:
3. サブクラス オブジェクトを作成するとき、サブクラスのどのコンストラクターが使用されるかに関係なく、親クラスの引数なしのコンストラクターがデフォルトで常に呼び出されます。親クラスが引数なしのコンストラクターを提供していない場合は、親クラスが引数なしのコンストラクターを提供する必要があります。の
サブクラスのコンストラクターで super を使用して、親クラスの初期化を完了するために親クラスのどのコンストラクターを使用するかを指定します。そうしないと、コンパイルが通過しません [例]
package com.hspedu.extend_;
public class Extendtail {
public static void main(String[] args) {
//尽管Sub类中的方法没有调用父类的无参构造器,但是也会显示父类无参构造器相关信息,然后显示子类的无参构造器相关信息
Sub sub = new Sub();
System.out.println("============");
Sub sub1 = new Sub();
// sub.ok();
}
}
テスト結果: デフォルトの親クラスの引数なしのコンストラクターが呼び出されます。
呼び出しコンストラクターを指定する
public class Base {
//无参构造器
// public Base(){
// System.out.println("父类的无参构造器Base()被调用....");
// }
public Base(String name, int age){
System.out.println("用的是父类第二个Base(String name, int age)");
}
}
public class Sub extends Base{
public Sub(){
// super();//默认调用父类的无参构造器,写不写都会被调用
//当父类的无参构造器被覆盖时,需要指定
//super在使用时,必须放在构造器的第一行
//super()和this()都只能放在构造器的第一行,因此这两个方法不能共存在一个构造器里面,第一行写了super(),就不能写this()
super("li",10);
System.out.println("子类的无参构造器Sub()被调用...");
}
public Sub(String name ){
//当父类的无参构造器被覆盖时,需要指定
super("chen",24);
System.out.println("子类有参构造器Sub(String name )被调用");
}
4. 親クラスのコンストラクターを呼び出すように指定する場合は、それを明示的に呼び出します: super(parameter list)
5. super を使用する場合は、コンストラクター (super) の最初の行に配置する必要があります。
6. super() と this() は両方ともコンストラクターの最初の行にのみ配置できるため、これら 2 つのメソッドはコンストラクター内で共存できません。
7. Java のすべてのクラスは Object クラスのサブクラスであり、Object はすべてのクラスの基本クラスです。
8. 親クラスのコンストラクターの呼び出しは、直接の親クラスに限定されません! オブジェクト クラス (最上位の親クラス) まで追跡されます。
9. サブクラスは、最大 1 つの親クラス (直接継承を参照)、つまり Java の単一の継承メカニズムのみを継承できます。
思考: クラス A にクラス B とクラス C を継承させるにはどうすればよいでしょうか?
答え: A は B を継承し、B は C を継承します。
継承の本質:
/*
* (1)先查看子类是否有该属性
* (2)如果子类有该信息,并且可以访问,则返回信息
* (3)如果子类没有该属性,就看父类有没有这个属性,如果父类有该属性,并且可以访问,则返回父类的该信息
* (4)如果父类的该属性不可以访问,继续找上一级的父类,直到找到object
* */
質問: オブジェクトの息子が年齢の属性にアクセスしたいが、親クラスの父の年齢が非公開で、祖父クラスの祖父の年齢が共有されている場合、祖父の年齢を取得できますか?
できません!Son は Father クラスにアクセスする際に age 属性をすでに見つけていますが、private でありアクセス権がないため、結果を取得できません。すでに見つかっているので探す必要もありませんし、アクセス権がないとも言わないので、おじいちゃんクラスのage属性を直接取得できます。
4.スーパーキーワード
super は親クラスへの参照を表し、親クラスのプロパティ、メソッド、コンストラクターにアクセスするために使用されます。
●基礎文法
1. 親クラスのプロパティにはアクセスしますが、親クラスのプライベート プロパティにはアクセスしません [case] super.プロパティ名;
2. 親クラスのメソッドにアクセスする場合、親クラスのプライベートメソッドにはアクセスできません [case] super.メソッド名(パラメータリスト);
3. 親クラスのコンストラクター (以前に使用したもの) にアクセスします: super (パラメーター リスト); はコンストラクターの最初の文にのみ配置でき、1 つの文のみを使用できます。
スーパーキーワード
1. 親クラスのコンストラクターを呼び出す利点 (分業が明確、親クラスのプロパティは親クラスによって初期化され、サブクラスのプロパティはサブクラスによって初期化されます) 2.サブクラス
のメンバーと同じ名前の親クラスのメンバー (プロパティとメソッド) が存在するため、親クラスのメンバーにアクセスするには、 super を渡す必要があります。重複する名前がない場合は、super、this、直接アクセスでも同じ効果があります!
3. super のアクセスは直接の親クラスに限定されません、grandpa クラスと this クラスに同じ名前のメンバーが存在する場合、スーパーを使用して、grandpa クラスのメンバーにアクセスすることもできます。複数の基本クラスに同じ名前のメンバーがある場合は、近接の原則に従ってスーパー アクセスを使用します。A->B->C もちろん、アクセス権に関するルールも遵守する必要があります
5.スーパーとこのキー
3. 書き換え・上書き
簡単に言うと、メソッドのオーバーライド (オーバーライド) とは、親クラスのメソッドと同じ名前、戻り値の型、パラメーターを持つメソッドがサブクラスにあることを意味します。その場合、サブクラスのメソッドが親クラスのメソッドをオーバーライドすると言います。
1. サブクラス メソッドのパラメータおよびメソッド名は、親クラス メソッドのパラメータおよびメソッド名とまったく同じである必要があります。
2 サブクラス メソッドの戻り値の型は、親クラス メソッドの戻り値の型、または親クラスの戻り値の型のサブクラスと同じです。
たとえば、親クラスの戻り値の型は Object で、サブクラスのメソッドの戻り値の型は String です。
【デモ】
public class Animal {
public void ask(){
System.out.println("动物在叫唤.....");
}
public Object m1(){
return null;
}
}
public class Dog extends Animal {
public void cry(){
System.out.println("wangwang......");
}
//和public object m1()构成重写
public String m1(){
return null;
}
}
【練習問題 1】:
1. 属性 private (名前、年齢)、コンストラクター、say メソッド (自己紹介の文字列を返す) を含む Person クラスを作成します。
2. Studentクラスを記述し、Personクラスを継承し、id、score属性private、コンストラクタを追加し、sayメソッド(自己紹介情報を返す)を定義します。
3. main で person オブジェクトと Student オブジェクトをそれぞれ作成し、say メソッドを呼び出して自己紹介を出力します。
サブクラスで super() を使用する利点を体験してください。
1. パーソン クラス、親クラス
package com.hspedu.override_;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String say(){
return "我的名字是"+ name + "年龄是:" + age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
2.学生クラス
package com.hspedu.override_;
public class Student extends Person {
private int id;
private double score;
public Student(String name, int age, int id, double score) {
super(name, age);
this.id = id;
this.score = score;
}
public String say(){
return super.say() + "id= "+ id + "score = " +score;
}
public void setId(int id) {
this.id = id;
}
public void setScore(double score) {
this.score = score;
}
public int getId() {
return id;
}
public double getScore() {
return score;
}
}
3. テスト
package com.hspedu.override_;
public class MainT {
public static void main(String[] args) {
Person person = new Person("li",18);
System.out.println(person.say());
System.out.println("====");
Student student = new Student("li",18,2203,80);
System.out.println(student.say());
}
}