五.面向对象2--继承、封装、多态

    技术2022-08-03  78

    继承

    代码复用,更容易实现类的扩展;更方便建模; 一个类包含属性、方法、构造方法,继承可以继承父类的所有属性、方法(不包含构造方法),但不能访问父类的私有属性和方法; 类默认继承Object类; java类只能单继承,接口可以多继承; 子类与父类,方法名、形参列表相同; 子类返回值类型应小于等于父类;(void) 子类的权限应大于等于父类;(public)

    final

    修饰变量,则不可以在改变; 修饰方法,则子类不能重写,只能重载(不同的方法使用相同的方法名,参数数量不同 参数类型不全同); 修饰类,该类不允许在被继承;

    组合

    也可以实现代码复用,在一个类里定义个属性为另一个类;

    is关系:用继承,如学生是人,学生用人里的属性 has关系:用组合,如笔记本用芯片里的属性

    ==、equals、super
    package com.bhzt.threefeature; /** * Ctrl+鼠标左键:追踪源码 * Alt+7:Structure 类结构图 */ public class Person extends Object /*不写则默认 extends Object*/ { public String name; public int height; public void rest() { System.out.println("休息"); } public Person(){ System.out.println("person 构造方法"); } } package com.bhzt.threefeature; /** * 继承 * @author puhome * */ public/*子类的权限应大于等于父类*/ class Student extends Person { public int age; /** * 重写 */ public void/*子类返回值类型应小于等于父类*/ rest() { super.rest();//调用父类的方法 System.out.println("学生休息"); } public Student(String name,int height,int age){ this.name=name; this.height=height; this.age=age; } /** * 打印信息 */ public void printText(){ System.out.println(this.name); System.out.println(this.height); System.out.println(this.age); } public Student(){ //默认会调用 super(); System.out.println("student 构造方法"); } } /** * 组合 * @author puhome * */ class Student2 { Person p=new Person(); } package com.bhzt.test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.bhzt.threefeature.Person; import com.bhzt.threefeature.Student; class ThreeFeatureTest { @Test void personTest() { Student s1=new Student("zhangsan",180,20); boolean b; if (s1 instanceof Person) { //s1对象是否属于Person类 b=true; } else { b=false; } System.out.println(s1.name); System.out.println(b); s1.rest(); } @Test void personTestTwo() { int n1=0; int n2=0; Student s1=new Student("zhangsan",180,20); Student s2=new Student("zhangsan",180,20); String t1="123"; String t2="123"; System.out.println(t1); System.out.println(n1==n2);//True 比较的是值是否相等 System.out.println(s1==s2);//false 比较的是对象地址是否一致 System.out.println(t1==t2);// 比较的是对象地址是否一致 System.out.println(s1.equals(s2));//false 比较的是对象,Object.equals System.out.println(t1.equals(t2));//True String 类重写了equals方法,比较的是值 //--------------------------------------------------------------------------------- System.out.println("-----------------------------------------------------------------"); //变量放到栈,对象放到堆 String str1="456"; String str2=new String("456"); String str3=str2; String str4="456"; System.out.println(str1==str2);//对象地址不一样 System.out.println(str1==str4);//对象地址一样 System.out.println(str2==str3);//对象地址一样 } @Test void superTest() { Student s1=new Student();//构造方法中 会默认调用父类的构造方法 } }

    封装

    高内聚 低耦合 高内聚:封装细节,便于修改内部代码,提高可维护性 低耦合:简化外部调用,便于调用者使用,便于扩展和协作

    访问限制修饰符

    修饰符同一个类同一个包子类所有类private√default(默认没有)√√protected√√√public√√√√

    default:只能邻居用,即使是儿子 不是邻居也不能用 protected:邻居能用,儿子即使不是邻居也能用,但有一点,儿子如果不是邻居(不在同一包) 则不能访问父类对象的成员方法

    package com.bhzt.encapsulation; public class Person { protected int testProtected=100; } package com.bhzt.encapsulationTwo; import com.bhzt.encapsulation.Person; public class Teacher extends Person { void test1() { Person p=new Person(); //System.out.println(p.testProtected);//不同包,子类不能访问父类对象的protected 成员 } void test2() { System.out.println(super.testProtected);//不同包,子类可以用此方式访问父类对象的protected成员 } }

    经验总结: 属性都用private修饰,在提供相应的访问方法用public修饰;

    JavaBean

    package com.bhzt.encapsulation; /** * 选中待封装属性,Refactor/Encapsulation Fields * 一个简单的JavaBean */ public class Person { protected int testProtected=100; private String name; private int age; private boolean flag; 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 boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } }

    多态

    多态,指同一个方法调用,由于对象不同可能会有不同的行为。 1.多态是方法的多态,与属性无关 2.多态存在的3个条件,继承、方法重写、父类引用指向子类对象 3.父类引用指向子类对象后,用该父类引用调用子类重写的方法

    package com.bhzt.polymorphism; public class Animal { public void shout(){ System.out.println("发出声音"); } } package com.bhzt.polymorphism; public class Cat extends Animal { @Override public void shout() { System.out.println("喵喵喵"); } public void seePark(){ System.out.println("猫看院"); } } package com.bhzt.polymorphism; public class Dog extends Animal { @Override public void shout() { System.out.println("汪汪汪"); } public void seeDoor() { System.out.println("狗看门"); } } package com.bhzt.polymorphism; public class ShoutAll { // public static void startShoutDog(Dog animal) // { // animal.shout();//如果不用多态,则每增加一个动物,都需要重载一次 // } // public static void startShoutCat(Cat animal) // { // animal.shout();//如果不用多态,则每增加一个动物,都需要重载一次 // } public static void startShout(Animal animal) { animal.shout();//多态,如果不用多态,则每增加一个动物,都需要重载一次 } } package com.bhzt.test; import com.bhzt.polymorphism.Animal; import com.bhzt.polymorphism.Cat; import com.bhzt.polymorphism.Dog; import com.bhzt.polymorphism.ShoutAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; /** * 多态 */ class PolyTest { @Test public void shoutTest() { Animal a1=new Dog();//父类引用子类对象 ShoutAll.startShout(a1); Cat c1=new Cat(); ShoutAll.startShout(c1);//父类引用子类对象 //类型转换---------------------------- Animal a2=new Dog();//向上类型转换,自动转,Dog 转 Animal //a2.seeDoor();Dog里的自定义方法 不能直接调用 // Dog d2=(Dog) a2;//向下强制转换,Animal转Dog // d2.seeDoor(); if(a2 instanceof Dog) { Dog d2 = (Dog) a2;//向下强制转换,Animal转Dog d2.seeDoor(); } //Cat c2=(Cat)a2; //c2.seePark();//编译能通过,但执行会异常 } }
    Processed: 0.013, SQL: 9