オブジェクト指向:
オブジェクト指向の3つの特性:カプセル化、継承、多形性
1つ:パッケージ
1.方法は一種の包装です
2.キーワードprivateも一種のカプセル化です
カプセル化とは、外の世界には見えない詳細な情報を隠すことです。
package com.dcits.day05.demo03;
public class Demo02Method {
public static void main(String[] args) {
int[] array = {5,15,25,35,111};
int max = getMax(array);
System.out.println(max);
}
public static int getMax(int[] array) {
int max = array[0];
for (int i = 0; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
return max;
}
}
private关键字的作用以及使用
プライベートが変更に使用されると、このクラスに自由にアクセスできますが、このクラスの範囲を超えてアクセスすることはできなくなります。
間接アクセスを介してGetter / Setterメソッドのペアをカスタマイズできます。これは、setXxxまたはgetXxxと呼ばれる必要があります。
Getterの場合、パラメーターは存在できず、戻り値のタイプはメンバー変数に対応します
セッターの場合、戻り値はありません。パラメータータイプはメンバー変数に対応します。
// Person类
package com.dcits.day05.demo03;
public class Person {
String name;
private int age;
public void show() {
System.out.println("我叫:" + name +",今年" + age);
}
public void setAge(int num) {
if (num < 100 && num >=9) {
age = num;
} else {
age = 0;
System.out.println("数据不合理");
}
}
public int getAge() {
return age;
}
}
// 调用
package com.dcits.day05.demo03;
public class Demo03Person {
public static void main(String[] args) {
Person person = new Person();
person.name = "赵丽颖";
// person.age = 18; 当成员变量被private修饰的时候,外部无法访问,只能通过间接的方式Setter,Getter
person.setAge(-20);
person.show();
}
}
ブール型の特殊なケース
// 类
package com.dcits.day05.demo03;
public class Student {
private String name;
private int age;
private boolean male;
public void setMale(boolean b){
male = b;
}
public boolean isMale() {
return male;
}
public void setName(String str){
name = str;
}
public String getName() {
return name;
}
public void setAge(int num) {
age = num;
}
public int getAge() {
return age;
}
}
// 调用
package com.dcits.day05.demo03;
public class Demo04Student {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("alex");
stu.setAge(10);
stu.setMale(true);
System.out.println(stu.getName());
System.out.println(stu.getAge());
System.out.println(stu.isMale());
}
}
this关键字的使用
メソッドのローカル変数とクラスのメンバー変数が同じ名前の場合、近接の原則に従って、ローカル変数が優先されます。このクラスのメンバー変数にアクセスする必要がある場合は、次の形式を使用する必要があります:this。membervariable
メソッドが呼び出されるのは誰ですか、これは誰ですか
// 类
package com.dcits.day05.demo04;
public class Person {
String name;
public void sayHi(String name) {
System.out.println(this.name + "你好,我是" + name);
}
}
// 调用
package com.dcits.day05.demo04;
public class Demo01Person {
public static void main(String[] args) {
Person person = new Person();
person.name = "6666";
person.sayHi("777");
}
}
构造方法
構築メソッドは、オブジェクトを作成するために特別に使用されるメソッドです。キーワードnewを使用してオブジェクトを作成する場合、実際には構築メソッドを呼び出します。
予防:
* 构造方法的名称必须和所在的类名称完全一样,就连大小写也要完全一样
* 构造方法不要写返回值类型,连void都不要写
* 构造方法不能return一个具体的返回值
* 如果没有编写任何构造方法,那么编译器默认会赠送一个构造方法,没有参数、方法体什么都不做
* 一旦编写了一个构造方法,那么编译器就不再赠送
* 构造 方法也是可以重载的
// 类
package com.dcits.day05.demo04;
public class Student {
private String name;
private int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
System.out.println("有参数的构造方法!!");
}
public Student() {
System.out.println("无参数的构造方法执行啦!!");
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
// 调用
package com.dcits.day05.demo04;
public class Demo02Student {
public static void main(String[] args) {
Student stu = new Student();
Student stu1 = new Student("aaa",20);
stu1.setAge(23);
System.out.println(stu1.getAge());
System.out.println(stu1.getName());
}
}
局部变量和成员变量
1.定义的位置不一样
* 局部变量:在方法的内部
* 成员变量:在方法的外部,直接写在类当中
2.作用范围不一样
*局部变量:只有方法 才可以使用,出了方法就不能再使用了
*成员变量:整个类都可以通用
3.默认值不一样
*局部变量:没有默认值,如果想要用,必须手动赋值
*成员变量:如果没有赋值,会有默认值,规则和数组一样
4.内存的位置不一样
*局部变量:位于栈内存
*成员变量:位于堆内存
5.生命周期不一样
*局部变量:随着方法进栈而诞生,随着方法出栈而消失
*成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失
标准类的组成部分
標準クラスには通常、次の4つの部分があります。
1. 所有的成员变量都要使用private关键字来修饰
2. 为每一个成员变量编写一对Getter、Setter方法
3. 编写一个无参数的构造方法
4. 编写一个全参数的构造方法
2:継承
継承は多形性の前提であり、継承がなければ多形性はありません
継承によって解決される主な問題は次のとおりです。共通性の抽出
クラスを定義する際の2つの考慮事項:
- メンバー変数は、メソッドの外部のクラスで直接定義されます
-
メンバーメソッドに静的キーワードを記述しないでください
继承的格式:
// 父类 package com.dcits.day08.demo01; public class Employee { public void method() { System.out.println("父类执行!"); } } // Teacher子类 package com.dcits.day08.demo01 public class Teacher extends Employee{ } // Assistant子类 package com.dcits.day08.demo01; public class Assistant extends Employee { } // 调用 package com.dcits.day08.demo01; public class Demo01Extends { public static void main(String[] args) { Teacher teacher = new Teacher(); Assistant assistant = new Assistant(); teacher.method(); assistant.method(); } }
在父子类的继承关系当中,如果成员变量重名,则创建子类时,访问有两种方式:
-
サブクラスオブジェクトを介してメンバー変数に直接アクセスする
等号の左側にいる人は誰でも使用されている人を優先し、ない場合は調べます
-
-
メンバーメソッドを介して間接的にメンバー変数にアクセスする
该方法属于谁,就优先用谁,没有则向上找
// 父类 package com.dcits.day08.demo02; public class Fu { int numFu = 10; int num = 100; public void methodFu() { System.out.println(num); } } // 子类 package com.dcits.day08.demo02; public class Zi extends Fu { int numZi = 20; int num = 200; public void methodZi() { System.out.println(num); } } // 调用 package com.dcits.day08.demo02; public class Demo01ExtendsField { public static void main(String[] args) { Fu fu = new Fu(); System.out.println(fu.numFu); Zi zi = new Zi(); System.out.println(zi.numFu); System.out.println(zi.numZi); // 当父类与子类的成员变量重名的时候 System.out.println(zi.num); // System.out.println(zi.abc); // zi.methodZi(); zi.methodFu(); } }
区分子类方法中的三种重名变量
- 直接使用されるメソッドの変数
- this。変数名:このクラスのメンバー変数を呼び出します
-
スーパー変数名:親クラスのメンバー変数を呼び出します
// 父类 package com.dcits.day08.demo03; public class Fu { int num = 10; } // 子类 package com.dcits.day08.demo03; public class Zi extends Fu { int num = 20; public void method() { int num = 30; System.out.println(num); // 30 局部变量 System.out.println(this.num); // 20 本类的成员变量 System.out.println(super.num); // 10 父类的成员变量 } } // 调用 package com.dcits.day08.demo03; public class Demo01ExtendsField { public static void main(String[] args) { Zi zi = new Zi(); zi.method(); } }
继承中成员方法的访问特点
親クラスと子クラスの継承関係では、サブクラスオブジェクトを作成し、メンバーメソッドにアクセスするためのルール:作成されたオブジェクトが最初に使用され、そうでない場合は検索されます。
注:メンバーメソッドであるかメンバー変数であるかにかかわらず、そうでない場合は、親クラスuを検索し、子クラスを検索することはありません。
// 父类 package com.dcits.day08.demo04; public class Fu { public void methodFu() { System.out.println("父类中的方法执行啦!"); } public void method() { System.out.println("父类重名执行啦!"); } } // 子类 package com.dcits.day08.demo04; public class Zi extends Fu { public void methodZi() { System.out.println("子类中的方法执行啦!"); } public void method() { System.out.println("子类重名执行啦!"); } } // 调用 package com.dcits.day08.demo04; public class Zi extends Fu { public void methodZi() { System.out.println("子类中的方法执行啦!"); } public void method() { System.out.println("子类重名执行啦!"); } }
继承方法中的覆盖重写
書き換え:メソッドの名前は同じ、パラメータリストは同じ、上書き、上書き
過負荷:メソッド名は同じですが、パラメーターリストは異なります
メソッドカバレッジと書き換え特性:サブクラスオブジェクトを作成します。サブクラスメソッドが推奨されます
メソッドオーバーライドに関する注意:
- メソッド名とパラメーターリストが親クラスと子クラスで同じであることを確認する必要があります
- @Override:メソッドの前に書き込んで、上書きが有効で正しいかどうかを確認します。このコメントが書き込まれていなくても、要件を満たしている限り、正しい上書きでもあります。
- サブクラスメソッドの戻り値は、親メソッドの戻り値の範囲以下である必要があります。オブジェクトクラスは、すべてのクラスの親クラスです
- サブクラスメソッドの権限は、親メソッドの権限修飾子以上である必要があります。public> protected>(デフォルト)> private注:(デフォルト)はキーワードdefaultではありませんが、何も記述せず、空白のままにし
、継承されたメソッドのアプリケーションシナリオをオーバーライドします// 父类 package com.dcits.day08.demo06; // 本来的老款手机 public class Phone { public void call() { System.out.println("打电话"); } public void send() { System.out.println("发短信"); } public void show() { System.out.println("显示号码"); } } // 子类 package com.dcits.day08.demo06; // 上市的新款手机 public class NewPhone extends Phone { @Override public void show() { // System.out.println("显示号码"); super.show(); System.out.println("显示姓名"); System.out.println("显示头像"); } } // 调用 package com.dcits.day08.demo06; public class Demo01Phone { public static void main(String[] args) { Phone phone = new Phone(); phone.call(); phone.send(); phone.show(); System.out.println("==========="); NewPhone newPhone = new NewPhone(); newPhone.call(); newPhone.send(); newPhone.show(); } }
继承中构造方法的访问特点
- サブクラス構築メソッドにはデフォルトの暗黙的な「super()」呼び出しがあるため、最初に呼び出される親クラス構築である必要があり、サブクラス構築は後で実行されます。
- サブクラス構造は、superキーワードを介して親クラスのオーバーロード構造を呼び出すことができます
- スーパークラスのスーパーストラクチャー呼び出しは最初のステートメントのみであり、サブクラスストラクチャーに対してスーパーストラクチャーを複数回呼び出すことはできません。
- サブクラスは親クラスの構築メソッドを呼び出す必要があります。ギフトsuper()を作成しない場合は、作成することでスーパー呼び出しを指定できます。スーパーは1つしか存在できず、最初のスーパーである必要があります。
super关键字的用法(访问父类的内容):
- サブクラスのメンバーメソッドで、親クラスのメンバー変数にアクセスします
- サブクラスのメンバーメソッドで、親クラスのメンバーメソッドにアクセスします
- サブクラスの構築メソッドで、親クラスの構築メソッドにアクセスします
// 父类 package com.dcits.day08.demo08; public class Fu { int num = 10; public void method(){ System.out.println("父类方法"); } } // 子类 package com.dcits.day08.demo08; public class Zi extends Fu { int num = 20; public Zi(){ super(); } public void methodZi() { System.out.println(super.num); // 父类的num } public void method(){ super.method(); System.out.println("子类方法"); } }
this关键字的三种使用方法(访问本类的内容)
- このクラスのメンバーメソッドで、このクラスのメンバー変数にアクセスします
- このクラスのメンバーメソッドで、このクラスの別のメンバーメソッドにアクセスします
- このクラスの構築方法で、このクラスの別の構築方法にアクセスして
ください。注:- 3番目の使用法に注意してください:this(..)呼び出しは、構築メソッドのステートメントである必要があります。
- スーパーの2つの建設呼び出しとこれを同時に使用することはできません
// 父类 package com.dcits.day08.demo09; public class Fu { int num = 30; } // 子类 package com.dcits.day08.demo09; public class Zi extends Fu { int num = 20; public Zi(){ this(123); // 本类的无参构造,调用本类的有参构造 // this(1,2) } public Zi(int n){ } public Zi(int n,int m){ } public void showNum(){ int num = 10; System.out.println(num); System.out.println(this.num); // 本类中的成员变量 System.out.println(super.num); // 父类中的 成员变量 } public void methodA() { System.out.println("AAA"); } public void methodB() { methodA(); this.methodA(); System.out.println("BBB"); } }
this、super的关键字图解
Java言語継承の3つの特徴: - クラスの直接の親は1つだけです。
- Java言語は複数を継承できます
- サブクラスの直接の親は一意ですが、親は多くのサブクラスを持つことができます
3:多形性:
多态的定义以及基本使用
継承を拡張したり、実現を実装したりすることは、多態性の前提です。
Xiao Mingのオブジェクトには、学生形式と人間形式の両方があります。オブジェクトには多くの形式があります。これは次のとおりです。多態性はオブジェクトの多態性
コードに反映されます。実際、これは1つの文です。親クラスの参照はサブクラスオブジェクトを指します。
フォーマット:
- 親クラス名オブジェクト名=新しいサブクラス名()
-
インターフェイス名オブジェクト名=新しい実装クラス名()
// 父类 package com.dcits.day09.demo04; public class Fu { public void method(){ System.out.println("父类方法"); } public void methodFu(){ System.out.println("父类特有方法"); } } // 子类 package com.dcits.day09.demo04; public class Zi extends Fu { @Override public void method() { System.out.println("子类方法"); } } // 调用 package com.dcits.day09.demo04; public class Demo01Multi { public static void main(String[] args) { // 使用多态的写法 // 左侧父类的引用指向右侧子类的对象 Fu obj = new Zi(); // new 的是谁就调用谁 的方法 obj.method(); // 子类方法 obj.methodFu(); // 父类特有方法 } }
多态中成员变量的使用特点
メンバー変数にアクセスする2つの方法:
- オブジェクト名から直接メンバー変数にアクセスし、等号の左側に誰がいるかを確認します。最初に使用するのは誰か、そうでない場合は検索します。
- メンバーメソッドを介したメンバー変数への間接アクセス。メソッドが誰に属しているか、誰を最初に使用するかを確認し、そうでない場合は、上記のように検索します。
// 父类 package com.dcits.day09.demo05; public class Fu { int num = 10; public void showNum(){ System.out.println(num); } } // 子类 package com.dcits.day09.demo05; public class Zi extends Fu { int num = 20; int age = 16; @Override public void showNum() { System.out.println(num); } } // 调用 package com.dcits.day09.demo05; public class Demo01MultiField { public static void main(String[] args) { Fu obj = new Zi(); System.out.println(obj.num); // 父类中的10 System.out.println("====================="); obj.showNum(); // 子类没有覆盖重写,就是父类中的num,一旦子类重写后就是子类中的num } }
多态中成员方法的使用特点
多態的なコードでは、メンバーメソッドの優先アクセスルールは次のとおりです。誰が新しいかを確認するには、誰が使用されているかを優先し、持っていない場合は検索します。
注:コンパイルについては左を、実行については右を参照してください
比較する
-
メンバー変数:左にコンパイルし、左に実行します
- メンバーメソッド:コンパイルして左側を見て、実行して右側を見てください
// 父类 package com.dcits.day09.demo05; public class Fu { int num = 10; public void showNum(){ System.out.println(num); } public void method(){ System.out.println("父类方法"); } public void methodFu(){ System.out.println("父类特有方法"); } } // 子类 package com.dcits.day09.demo05; public class Zi extends Fu { int num = 20; int age = 16; @Override public void showNum() { System.out.println(num); } @Override public void method() { System.out.println("子类方法"); } public void methodZi(){ System.out.println("子类特有方法"); } } // 调用 package com.dcits.day09.demo05; public class Demo01MultiField { public static void main(String[] args) { Fu obj = new Zi(); obj.method(); // 父子都有,优先使用子类 obj.methodFu(); // 子类没有,父类有,向上找到父类 // 编译看左,左边是Fu,没有methodZi方法,所以编译报错 // obj.methodZi(); // 错误写法 // System.out.println(obj.num); // 父类中的10 // System.out.println("====================="); // obj.showNum(); // 子类没有覆盖重写,就是父类中的num,一旦子类重写后就是子类中的num } }
使用多态的好处
对象的向上转型
オブジェクトの上方への変換は、実際には多態的なアプローチです
形式:親クラス名オブジェクト名=新しいサブクラス名()
意味:右側にサブクラスオブジェクトを作成し、それを親クラスとして扱います
予防:
-
小さな領域から大きな領域への上方への移行は安全でなければなりません
- ただし、欠点があります。オブジェクトが親クラスに変換されると、サブクラスの元の一意のコンテンツを呼び出すことができなくなります。
類似:double num = 100正しいint ---- double自動型変換
// 父类
package com.dcits.day09.demo06;
public abstract class Animal {
public abstract void eat();
}
// 子类
package com.dcits.day09.demo06;
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼。。。");
}
}
// 调用
package com.dcits.day09.demo06;
public class Demo01Main {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat();
}
}
对象的向下转型
オブジェクトの下方への変換は、実際には削減アクションです
形式:サブクラス名オブジェクト名=(サブクラス名)親クラスオブジェクト
意味:親クラスオブジェクトを元のサブクラスオブジェクトに復元します
予防:
-
オブジェクトを猫に変換する前に、作成時にオブジェクトが猫であることを確認する必要があります。
- オブジェクトが作成されたときに猫ではなかったが、今は猫に変換する必要がある場合、エラーが報告されます
類似:int num =(int)10.0正しいint num =(int)10.5エラー、精度の低下
// 父类
package com.dcits.day09.demo06;
public abstract class Animal {
public abstract void eat();
}
// 猫子类
package com.dcits.day09.demo06;
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼。。。");
}
public void catchMouse() {
System.out.println("猫抓老鼠!!");
}
}
// 狗子类
package com.dcits.day09.demo06;
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃shit");
}
public void watchMouse() {
System.out.println("狗看家!!");
}
}
// 调用
package com.dcits.day09.demo06;
public class Demo01Main {
public static void main(String[] args) {
Animal animal = new Cat(); // 对象的向上转型
animal.eat();
// 向下转型
Cat cat = (Cat) animal;
cat.catchMouse(); // 猫抓老鼠!!
// 下面是错误的向下转型
// 本来new的时候是一只猫,现在非要转成狗
// java.lang.ClassCastException
Dog dog = (Dog) animal; // 错误写法
}
}
接口多态的综合案例
// USB接口类:两个抽象方法:打开USB、关闭USB
package com.dcits.day09.demo07;
public interface USB {
public abstract void open();
public abstract void close();
}
// 电脑类:开机、关机、连接USB接口并对USB设备进行对应操作
package com.dcits.day09.demo07;
public class Computer {
public void powerOn(){
System.out.println("笔记本电脑开机");
}
public void powerOff(){
System.out.println("笔记本电脑关机");
}
// 使用USB设备的方法,使用接口作为方法的参数
public void useDevice(USB usb) {
usb.open();
// 判断当前类是属于哪个类之后,在获取类中的特有方法
if (usb instanceof Mouse){
Mouse mouse = (Mouse) usb;
mouse.click();
} else if (usb instanceof KeyBoard){
KeyBoard keyboard = (KeyBoard) usb;
keyboard.type();
}
usb.close();
}
}
// 鼠标类:重写接口类中的打开、关闭功能,并实现自己的独有功能
package com.dcits.day09.demo07;
public class Mouse implements USB {
@Override
public void open() {
System.out.println("打开鼠标");
}
@Override
public void close() {
System.out.println("关闭鼠标");
}
public void click(){
System.out.println("点击鼠标!");
}
}
// 键盘类:重写接口类中的打开、关闭功能,并实现自己的独有功能
package com.dcits.day09.demo07;
public class KeyBoard implements USB {
@Override
public void open() {
System.out.println("打开键盘");
}
@Override
public void close() {
System.out.println("关闭键盘");
}
public void type(){
System.out.println("敲键盘!");
}
}