javaSE(从0开始)day09

目录

面向对象的三大特征:

一、继承:

 1、定义:

 2、特点:   

(1)java允许单继承,不允许多继承

(2)允许多级继承

(3)允许一个父类拥有多个子类

3、 继承树:

4、protected 关键字:

5、super 关键字:

    (1)super关键字:

        2、super():

6、向上转型:

                  1、直接转:

                  2、参数转:

                  3、返回值做到了上转型

7、向下转型:

二、方法重写:

            1、定义:

2、调用super:

3、 final关键字

          2、用final修饰的方法不能被Override:用final修饰的类不能被继承。如果一个类不希望任何其他类继承自它,那么可以把这个类本身标记为final。

         3、对于一个类的实例字段,同样可以用final修饰。用final修饰的字段在初始化后不能被修改。

        4、对final字段重新赋值会报错

         5、可以在构造方法中初始化final字段:这种方法更为常用,因为可以保证实例一旦创建,其final字段就不可修改。

三、多态:


面向对象的三大特征:

一、继承:

 1、定义:

      继承是面向对象编程中非常强大的一种机制,它首先可以复用代码。当我们让子类从父类继承时,子类就获得了父类的所有功能,我们只需要为子类编写新增的功能。Java中使用extends关键字来实现继承: 

修饰符 class 子类名 extends 父类{

    // 非私有的成员变量

   // 非私有的成员方法

  // 自定义成员变量和成员方法

 }

 2、特点:   

(1)java允许单继承,不允许多继承
(2)允许多级继承
(3)允许一个父类拥有多个子类
package com.yuan;

public class Demo01 {
    public static void main(String[] args) {
        C c = new C();
        c.hello();
    }
}
class A{
    public  void hello(){
        System.out.println("hello");
    }
}
class B extends A{

}
class C extends B{

}

3、 继承树:

      我们在定义父类的时候,没有写extends。在Java中,没有明确写extends的类,编译器会自动加上extends Object。所以,任何类,除了Object,都会继承自某个类。下图是PersonStudent的继承树:

                                     

4、protected 关键字:

       使用范围: 可以让子类和同包下的类访问。

       继承有个特点,就是子类无法访问父类的private字段或者private方法。例如,Student类就无法访问Person类的nameage字段: 

  class Person {
    private String name;
    private int age;
}

class Student extends Person {
    public String hello() {
        return "Hello, " + name; // 编译错误:无法访问name字段
    }
}

          使用protected继承的作用就会被削弱了。为了让子类可以访问父类的字段,我们需要把private改为protected。用protected修饰的字段可以被子类访问:

class Person {
    protected String name;
    protected int age;
}

class Student extends Person {
    public String hello() {
        return "Hello, " + name; // OK!
    }
}

5、super 关键字:

    (1)super关键字:

          表示父类(超类)。子类引用父类的字段时,可以用super.fieldName。例如:

class Student extends Person {
    public String hello() {
        return "Hello, " + super.name;
    }
}

        2、super():

        子类在继承父类的时候,子类的构造方法会默认调用父类的无参构造方法,如果父类没有无参构造,需要手动调用父类的有参构造:

//定义父类
public class Person {
    public String cardId;
    protected String name;
     protected int age;
     //定义有参构造默认无参构造没有

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
//定义子类
class Student extends Person{
    public int score;
    public String name;
    //子类的构造方法会默认调用父类的无参构造方法
    // 如果父类没有无参构造,需要手动调用父类的有参构造
    public Student(){
        //手动调用
        super("张三",8);
    }
    public Student(String name, int age,int score) {
        super(name, age);
        this.score=score;
    }

    //就近原则
    //如果此方法有变量,则优先用此方法的局部变量
    //如果此方法没有这个局部变量,则找本类的成员变量
    //如果本类的成员变量没有,则找父类
    //如果强制指代此变量为本类,可以用this,如果声明此变量为父类的用super
    //Object 中的equals方法比较地址
    public void showMessage(String name) {
        System.out.println( "使用super调用:{" + "name='" + super.name  + ", age=" +  super.age + ", score=" +  this.score + '}');
        System.out.println( "使用this调用:{" + "name='" + this.name  + ", age=" + this.age + ", score=" + this.score + '}');
        System.out.println( "不使用关键字调用:{" + "name='" + name  + ", age=" + age + ", score=" + score + '}');  //就近原则
    }
}
class Test{
    public static void main(String[] args) {
        Student student = new Student();
//        System.out.println(student.name);
//        System.out.println(student.age);

        //有参构造
        Student student1 = new Student("王麻子",18,100);
//        System.out.println(student1.name);
//        System.out.println(student1.age);

        student1.showMessage("李四");


    }
}

6、向上转型:

     父类的引用执行具体的子类 只能使用父类拥有的

三种方式:

                  1、直接转:

直接向上转型:父类的引用执行具体的子类 只能使用父类拥有的

Animal2 a1=new Cat2("花花",3,'黑');  //第一种

Brid b3=new Brid("点点",2,'白');  //第二种

Animal2 a3=b3; //向上转型

                  2、参数转:

Brid b1 = new Brid("扁扁", 2, '彩');

keepPet(b1, "谷子");//2、参数的向上  keepPet(Animal a,int age ,char ch){}

                  3、返回值做到了上转型

public static Animal getAnimal(){

        return new Brid("扁扁", 2, '彩');

}

7、向下转型:

      将对外声明的父类对象转回为具体的子类,向下转型,具有不安全的。可能会出现类型转换异常ClassCastException ,所有的向下转型在进行转换前,需要进行判断,判断当前对象是否属于要转的这种类型

Animal2 a4=new Cat2("花花",3,'黑');

System.out.println(a4.weight);

a4.catchMouse();  //报红 是Cat独有的方法 需要向下转型为Cat类型

Cat2 c4=(Cat2)a4;

System.out.println(c4.weight);

c4.catchMouse();

2、

 Animal2 a5=new Brid("点点",2,'白');

Brid b4=(Brid) a5; //向下转型

b4.fly();/// 使用自己独有的方法

b4.eat("虫子"); //自己为定义eat 此时使用父类eat 

3、子类之间不可以相互转型:会出现类型转换异常  使用instanceof 判断是不是同一个类型

 Animal2 a6=new Cat2("远远",3,'黑');

if(a6 instanceof Brid) {    //结果为布尔类型

       Brid c1 = (Brid) a6; //子类之间不可相互转型 类型转换异常

}else {

       System.out.println("不是鸟的类型");

}

二、方法重写:

            1、定义:

        在继承关系中,子类如果定义了一个与父类方法签名完全相同的方法,被称为重写(Override)。Override重写Overload重载不同的是:如果方法签名不同,就是Overload重载Overload重载方法是一个新方法;如果方法签名相同,并且返回值也相同,就是Override 重写。加上@Override注解可以让编译器帮助检查是否进行了正确的覆写。希望进行覆写,但是不小心写错了方法签名,编译器会报错。

class Person {
    public void run() { … }
}

class Student extends Person {
    // 不是Override,因为参数不同:
    public void run(String s) { … }
    
    // 不是Override,因为返回值不同:
    public int run() { … }
}

2、调用super:

     在子类的重写方法中,如果要调用父类的被覆写的方法,可以通过super来调用。

class Person {
    protected String name;
    public String hello() {
        return "Hello, " + name;
    }
}

Student extends Person {
    @Override
    public String hello() {
        // 调用父类的hello()方法:
        return super.hello() + "!";
    }
}

3、 final关键字

         1、 继承可以允许子类覆写父类的方法。如果一个父类不允许子类对它的某个方法进行覆写,可以把该方法标记为final

class Person {
    protected String name;
    public final String hello() {
        return "Hello, " + name;
    }
}

Student extends Person {
    // compile error: 不允许覆写
    @Override
    public String hello() {
    }
}

          2、用final修饰的方法不能被Override:用final修饰的类不能被继承。如果一个类不希望任何其他类继承自它,那么可以把这个类本身标记为final

final class Person {
    protected String name;
}

// compile error: 不允许继承自Person
Student extends Person {
    
}

         3、对于一个类的实例字段,同样可以用final修饰。用final修饰的字段在初始化后不能被修改。

class Person {
    public final String name = "Unamed";
}

        4、对final字段重新赋值会报错

Person p = new Person();
p.name = "New Name"; // compile error!

         5、可以在构造方法中初始化final字段:这种方法更为常用,因为可以保证实例一旦创建,其final字段就不可修改。

class Person {
    public final String name;
    public Person(String name) {
        this.name = name;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呼哧呼哧.

栓Q!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值