P284-继承P289Super关键字P302覆盖P306-P311多态

P284-继承P289Super关键字P302覆盖P306-P311多态 

P284无参数构造器与setXxx()方法集合练习1

 

package Encap;
​
public class Person {
    public static void main(String[] args) {
        Person1 p1 = new Person1();
        p1.setName("javakkkk");
        p1.setAge(200);
        p1.setSalary(9999);
        System.out.println(p1.info());
        Person1 p2 = new Person1("simi",400,999);//利用构造器指定属性
        System.out.println(p2.info());
    }
}
class Person1{
    public String name;
    private int age;
    private double salary;
​
​
    public Person1(String name, int age, double salary) {//有三个属性的构造器
        this.name = name;//如果是单独构造器就不具备setX()的作用
        this.age = age;
        this.salary = salary;
        //所以我们可以将set方法写入构造器
        setName(name);
        setAge(age);
        setSalary(salary);
​
​
    }
​
    public Person1() {
​
    }
​
    public int getAge(){
​
        return age;
    }
    public void setAge(int age){
        if(age <1 || age > 120){
            System.out.println("年龄需在1-120");
            this.age=20;
        }else{
            this.age=age;
        }
    }
​
    public void setName(String name) {
        if(name.length() >= 6 || name.length() <=2 ){
            System.out.println("名字长度不对,需要2-6");
            this.name="null";
        }else {
            this.name = name;
        }
    }
​
    public double getSalary(int a) {//可以增加对象的权限判断
        return a != 666 ? 0:salary;
    }
​
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public String info(){
        return("name= "+name+" age= "+age+" salary= "+salary);
    }
​
​
}
​

P285练习

package Encap;
​
public class Acount {
    private String name;
    private double balance;
    private String pwd;
​
    public Acount() {
​
    }
​
    public Acount(String name, double balance, String pwd) {
        this.setName(name);
        this.setBalance(balance);
        this.setPwd(pwd);
    }
​
​
    public void setName(String name) {
        if(name.length() > 4 || name.length() < 2){
            System.out.println("name在2-4位");
            this.name="无名";
        }else {
            this.name = name;
        }
    }
​
    public String getName() {
        return name;
    }
​
    public double getBalance() {
        return balance;
    }
​
    public void setBalance(double balance) {
        if(balance > 20.0) {
            this.balance = balance;
        }else{
            System.out.println("balance > 20,否则默认为0");
            this.balance=0.0;
        }
​
    }
​
    public String getPwd() {
        return pwd;
    }
​
    public void setPwd(String pwd) {
            if( pwd.length() == 6) {
                this.pwd = pwd;
            }else{
                System.out.println("密码必须为6位,否则默认000000");
                this.pwd="000000";
            }
    }
    public void info(){
        System.out.println("name= "+name +" balance=  "+balance +" pwd=  "+pwd);
    }
}
​
​
package Encap;
​
public class AcountTest {
    public static void main(String[] args) {
        Acount acount = new Acount();
        acount.setPwd("1234567");
        acount.setBalance(9);
        acount.setName("lllll");
        acount.info();
    }
}
​

P286继承

1.由于两个类许多属性和方法相同,所以需要继承

-----

2.继承的规则

image-20211228233848301

-----

3.代码

package com.extend;
//源类
public class Student {
​
    public String name;
    public int age;
    private double score;
​
    public void setScore(double score) {
        this.score = score;
    }
    public void showinfo(){
        System.out.println("学生 "+name +"  age  "+age+"  score  "+score);
    }
}
​

package com.extend;
​
//让pupil继承student
public class Pupil extends Student {
​
    public void testing(){
        System.out.println("小学生 "+name+" testing");
    }
}
​
​
package com.extend;
//让graduate继承student
public class Graduate extends Student {
    public void testing(){
        System.out.println("大学生  "+name+"  testing");
    }
​
}
package com.extend;
​
public class TestEx {//测试调用
    public static void main(String[] args) {
        Pupil p = new Pupil();
        p.name="Ada";
        p.age=10;
        p.testing();
        p.setScore(100);
        p.showinfo();
        System.out.println("=========");
        Graduate g = new Graduate();
        g.name="Beta";
        g.age=99;
        g.testing();
        g.setScore(150);
        g.showinfo();
​
    }
}

4.继承细节

image-20211229000515461

-

package com.extend;
​
//源类(个人比较喜欢叫源类)
public class Student {
​
    public int  n1=100;
    protected int n2=200;
    int n3=300;
    private int n4=400;
​
    public Student() {//无参构造器
        System.out.println("源类Student()构造器被调用");
    }
    public int getNe(){//源类提供一个公公共方法去访问n4
        return n4;
    }
    public void calltest400(){
        test400();
    }
    public void test100() {
        System.out.println("test100");
    }
    protected void test200(){
        System.out.println("test200");
    }
    void test300(){
        System.out.println("test300");
    }
    private void test400(){
        System.out.println("test400");
    }
}
​
package com.extend;
//让graduate继承student
public class Graduate extends Student {
    public Graduate() {
        super();//默认调用父类的无参构造器,写不写都可以
        system.out.println("子类Graduate()构造器被调用")
​
    }
    public void sayOK(){//子类的方法
        // 非私有的属性和方法在子类中可以直接访问,私有要通过公共方法去访问
        System.out.println(n1+n2+n3);//不能访问n4,不能访问test400();
        test100();
        test200();
        test300();
        //源类提供的公共方法去访问
        System.out.println("n4="+getNe());
        calltest400();
    }
}
​
package com.extend;
​
public class TestEx {//测试调用
    public static void main(String[] args) {
        Graduate g = new Graduate();
        g.sayOK();
    }
}

输出

源类Student()构造器被调用

子类Graduate()构造器被调用

600 test100 test200 test300 n4=400 test4

-具体可见上层述代码,源类构造器先调用,再调用子类的构造器

image-20211229111322411

-

第一句话理解(注意此时源类只有一个无参构造器)

package com.extend;
//让graduate继承student
public class Graduate extends Student {
    public Graduate() {
        System.out.println("子类的无参构造器被调用");
    }
    public Graduate(int n3){
        System.out.println("子类构造器int n3被调用()");//源类不变,增加一个构造器
​
    }
package com.extend;
​
public class TestEx {//测试调用
    public static void main(String[] args) {
        Graduate g = new Graduate();
        System.out.println("第二个对象");
        Graduate g2 = new Graduate(3000);
        g.sayOK();
        g2.sayOK();
​
    }
}
​

输出结果为

父类Student()无参构造器调用 子类的无参构造器被调用 第二个对象 父类Student()无参构造器调用 子类构造器int n3被调用() 600 test100 test200 test300 n4=400 test400 600 test100 test200 test300 n4=400 test400

第二句话理解(此时源类有Student(int 1,int2)构造器,将默认构造器覆盖了)

public class Student {
​
    public int  n1=100;
    protected int n2=200;
    int n3=300;
    private int n4=400;
​
    //public Student() {//无参构造器
       // System.out.println("父类Student()无参构造器调用");
   //}
    public  Student(int n1,int n2){
        System.out.println("源类Student(int n1,int n2)构造器被调用了");
    }
    
    
package com.extend;
​
​
//让graduate继承student
public class Graduate extends Student {
    public Graduate() {
        super(100,200);
        System.out.println("子类的Graduate构造器被调用");
​
    }
    public Graduate(int n3){
        super(100,200);
        System.out.println("子类构造器Graduate(int n3)被调用()");
​
    }
    

输出结果为

源类Student(int n1,int n2)构造器被调用了 子类的Graduate构造器被调用 第二个对象 源类Student(int n1,int n2)构造器被调用了 子类构造器Graduate(int n1,int n2)被调用()

image-20211229122925654

如果调用源类可以什么都不写,或者super();如果参数,比如name,super("jack");

image-20211229123701916

--

可以在ctrl+H察看类的关系

5.继承本质的分析(theoray原理)

package com.extend;
​
public class Theoray {
    public static void main(String[] args) {
        D d = new D();
        System.out.println(d.name+d.age+d.hobby);
    }
}
class G{
    String name="姥姥";
    String hobby="money";
}
class M extends G{
    String name="mon";
    int age =45;
}
class D extends M{
    String name="dau";
}

image-20211229124914843

-

顺序:

1.new D,继承关系Object-G-M-D,所以从D-M-G-O

2.对象在栈——在堆----方法区常量值存储String 类型数据

3.当访问D.属性的时候,先看子类是否有这个属性,如果有并且可以访问,则访问。

(上文说过如果私有变量可以通过父类方法进行访问

class M extends G{
    String name="mon";
    private int age =45;
​
    public int getAge() {
        return age;
    }
    
   //在System.out.println(d.name+d.getAge()+d.hobby);

注意一个点,上文比如我调用d.age,比如G和M都有age,M是私有,G是公有的,实际上不会调用,因为在M已经堵住了,有顺序的,所以不会继续调用G的age属性)

如果子类没有这个属性,就看源类继续上一级

依次输出 dau45money

6.面向对象的编程继承练习

image-20211229144422524

分析:B(){this("abc")执行下面构造器,然后返回A的无参构造器

练习2

public class Computer {
​
    private String cpu;
    private int memory;
    private int disk;
​
    public Computer(String cpu, int memory, int disk) {
        this.cpu = cpu;
        this.memory = memory;
        this.disk = disk;
        System.out.println("调用C(1,2,3)构造器");
    }
    public String getDetial(){
        return "cpu="+cpu+" memory="+memory+" disk="+disk;
    }
}
​
package com.extend;
​
public class PC extends Computer{
    private String band;
​
    public PC(String cpu, int memory, int disk, String band) {
        //IDEA根据继承的思想,父类继承的初始化
        //子类构造器完成子类属性的初始化
        super(cpu, memory, disk);
        this.band = band;
    }
    public void printInfo(){
        System.out.println(getDetial()+"brand= "+band);
        //通过父类的方法得到信息
    }
}
package com.extend;
​
public class NotePad extends Computer {
    private String color;
​
    public NotePad(String cpu, int memory, int disk, String color) {
        super(cpu, memory, disk);
        this.color = color;
    }
    public void Printinfo(){
        System.out.println(getDetial()+"color="+color);
    }
}
​
package com.extend;
​
public class Test {
    public static void main(String[] args) {
        PC pc = new PC("intel",4,5,"IBM");
        pc.printInfo();
​
​
​
        System.out.println("====第二个对象===");
        NotePad nP = new NotePad("tian",7,8,"blue");
        nP.Printinfo();

P289Super关键字

image-20211229162525854

--

public class A{
   public int a;
    private String b;
    double c;
​
    public A() {
        
    }
​
    public A(int a) {
        this.a = a;
    }
​
    public A(int a, String b, double c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    public void Testa(){
    }
    private void Testb(){
        
    }
}
public class B extends A{
    public int d;
    public void Test(){//调用父类的属性非private
        System.out.println(super.a+super.c);
    }
    public void OK(){//调用父类的方法,非private
        super.Testa();
    }
    public B(){
       // super ();继承无参构造器
        super (10);//调用的是父类的构造器,public A(int a)
        
    }
    
}
​

image-20211229170225569

-

package Super;
​
public class A {
   public int a;
    private String b;
    double c;
​
    public A(int a, String b, double c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    public void Testa(){
    }
}
class B extends A{
    public int d;
    public void OK(){//调用父类的方法,非private
        //当想要调用父类中的Testa()方法的时候,有三种方式
        //Testa();
        //找此方法的时候,顺序是先找本类,
        // 本类有再并且可以调用,则调用,
        // 无则找父类,一直找,直到Object类
        // 如果在过程中找到但不可访问则报错,或者方法不存在
       // this.Testa();//等价上述的Testa()
        super.Testa();//跳过子类(如果子类有同样名字的方法或者没有都会跳过)
        //是直接找父类的Testa(),后面步骤和上一样直到Object类
        
        //演示调用属性的规则,同上
        
        System.out.println(a);
        System.out.println(this.a);
        System.out.println(super.a);
​
}
​

image-20211229172800676

-

P302方法重写/覆盖(override)

image-20211229175105200

``

不一定是父子关系,只是相对而言,比如A-B-C,A-C之间也有可能

image-20211229175638893

-

重写可以通过编译,比如B继承A,父类返回类型A,子类返回类型可以为A也可以为B

注意,子类的范围不能缩小

image-20211229181859512

-

补充一下,重载的形参可以是普通参数+可变参数,可变参数放在最后且一个形参只能一个可变参数P235

练习code

package com;
​
public class Person {
    private String name;
    private int age;
​
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
​
    public String say(){//注意为了简洁,没有写set()和get()方法
       return  "name= "+name+"age= "+age;
    }
}
​
public class Student extends Person {
    private int id;
    private int score;
​
    public Student(String name, int age, int id, int score) {
        super(name, age);
        this.id = id;
        this.score = score;
    }
    public String say(){//此时属于方法重写了
        return super.say()+" id="+id+" score="+score;
    }
​
    public void setScore(int score) {
        this.score = score;
    }
}
​
package com;
​
public class OverdideExercise {
    public static void main(String[] args) {
        Person p1 = new Person("Pp",9);
        System.out.println(p1.say());
        System.out.println("第二个对象");
        Student s = new Student("Ss",20,6666,99);
        System.out.println(s.say());
    }
}

P306多态polymorphic

--

image-20211229214215983

---

2)对象的多态

上图 父类发引用 Anima; animal ,指向,子类的对象 new Dog();

package com.Polymoraphic.Exercise;
​
public class Animal {//父类
    public void cry(){
        System.out.println("A在叫");
    }
}
​
package com.Polymoraphic.Exercise;
​
public class Dog extends Animal {//子类1
    public void cry(){
        System.out.println("dog瞎叫");
    }
}
package com.Polymoraphic.Exercise;
​
public class Cat extends Animal//子类2
    public void cry(){
        System.out.println("cat在叫");
    }
}
package com.Polymoraphic.Exercise;
​
public class Test {
    public static void main(String[] args) {
        //体验对象的多态特点
       Animal animal= new Dog();//注意 Dog是Animal的子类才可以
       animal.cry();//因为运行时, 执行到该行时,animal
        // 运行类型是Dog,所以cry 就是Dog 的cry
        animal = new Cat();//编译还是animal,but 运行类型是Cat
        //运行的时候看的是堆里的指向
        animal.cry();
    }
}
​

public void feed(Animal animal,Food food){

\\ animal的编译类型是Animal ,可以指向接收Animal子类的对象

system.out.println(animal.getName +feed.getName)

}

P310多态的注意事项和细节

image-20211229231222150

向上引用 例如上文 A nimal animal = new Dog();code为举例

package com.Polymoraphic.Exercise;
​
public class Animal {
    public void eat(){
        System.out.println("A在eat");
    }
    public void run(){
        System.out.println("A在run~");
    }
    public void sleep(){
        System.out.println("A在sleep~");
    }
}
​
package com.Polymoraphic.Exercise;
​
public class Cat extends Animal{
    public void eat (){
        System.out.println("cat在eat");
    }
    public void catchM () {
        System.out.println("cat抓老鼠");
    }
}
package com.Polymoraphic.Exercise;
​
public class Test {
    public static void main(String[] args) {
        //向上转型,父类的引用指向子类的对象
        Animal animal=new Cat();
        //Object object = new Cat();也可以
        //可以访问父类中的所有成员(需遵守访问权限,比如private)
        /*但是不能访问子类的特有成员ainimal.catch
        因为在编译阶段,能调用哪些成员,由编译类型来决定
         */
        //最终运行效果看子类的具体实现,调用方法的时候从子类开始查找,规则与方法调用规则一致
        animal.eat();//cat在eat
        animal.run();//A在run~
        animal.sleep();//A在sleep~
    }
}
​

image-20211229231322356

向下转型

package com.Polymoraphic.Exercise;
​
public class Test {
    public static void main(String[] args) {
        //向上转型,父类的引用指向子类的对象
       Animal animal=new Cat();
        //向下转型,语法 子类类型 引用名=(子类类型)父类引用
        //此时编译类型Cat,运行类型也是Cat
        //(2)要求父类的引用必须指向的是当前目标类型的对象
        //意思是下行的animal实际上指向Cat对象,cat1也指向Cat对象
        //原本的时候animal>Animal,cat1>Cat对象
        //把指向猫的animal转向cat
        Cat cat1 = (Cat) animal;
        cat1.catchM();//调用这个方法,得到猫类的特有方法
        Animal animal1 = new Dog();
        Dog dog = (Dog) animal1;//个人认为多态的向下需要向上
        // 使得父类的引用指向当前目标类型的对象
        dog.cry();
   }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值