黑马程序员——java基础之继承和多态

——- android培训java培训、期待与您交流! ———-

继承:把类中公共的部分抽取出来,做成一个公共的类,让其他类和我们公共的类产生关系,让我们自己的类可以使用公共类。
    这个关系就是继承。
java中也可以有继承,java中的继承指的就是类与类的继承。
    格式:使用extends关键字。
        class 子类 extends 父类{

        }

被继承的那个类:我们称之为父类、基类、超类
继承的那个类:我们称之为子类、派生类。

继承的作用:
    相当于把父类中的内容,拿到了子类中。继承之后,父类中的成员,子类都可以访问(除了private)。

继承的优点:
    1.提高了代码的复用性
    2.提高了代码的可维护性。
    3.为多态提供了前提。
class Person {
    //名字
    String name;
    //年龄
    int age;
}

//自定义一个学生类
class Student extends Person {

    public void study(){    
        System.out.println("上课学习");
    }
}
//自定义一个教师类
class Teacher {
    public void teach(){
        System.out.println("讲课");
    }
}
class ExtendsDemo {
    public static void main(String[] args) {
        Student s = new Student();
        System.out.println(s.name);
    }
}
继承的特点:
    1.继承只能单继承。(一个人只能有一个亲生父亲,一个类只能有一个父类)
    2.继承可以多重(多层)继承。(一个人只能有一个亲生父亲,但是还可以有亲爷爷)
class Ye {
    int age;
}
class Fu extends Ye {
    String name;
}
class Zi extends Fu {

}
class ExtendsDemo2 {
    public static void main(String[] args) {
        Zi z = new Zi();
        System.out.println(z.name);
        System.out.println(z.age);
    }
}
继承的注意事项:
    1.继承必须是 “is a” 的关系
    2.私有的成员,因为权限问题,不能使用。
    3.java不支持部分继承。也就是说,如果继承就是全部继承。如果不继承就全部都不继承。
class Animal {
    String name;
    int age;
}
class Cat extends Animal {  

}
class Dog extends Animal {
}
class ExtendsDemo3 {
    public static void main(String[] args) {
        Cat c = new Cat();
        System.out.println(c.age);
    }
}
类在使用变量时:使用就近原则。
    继承间成员变量的使用规则:也是就近原则。
        a.先找方法内的局部变量
        b.再找本类的成员变量。
        c.再找父类的成员变量。
        d.如果还找不到,则报错。//找不到符号


当局部变量、本类成员变量、父类成员变量都重名时:
    使用局部变量:直接使用名字。//因为就近原则,就直接找到了。
    使用本类成员变量:this.成员变量
    使用父类成员变量:super.成员变量  

继承间成员变量的注意事项:
    1.访问父类的父类的成员变量,不能使用super.super
class Ye {
    int age = 80;
}

class Fu extends Ye {
    int age = 20;
    public int getYeAge(){
        return super.age;
    }

    int yeAge = super.age;
}

class Zi extends Fu{
    int age = 18;
    public void method(){
        int age = 16;
        System.out.println(age); //使用局部变量
        System.out.println(this.age); //使用本类成员变量
        System.out.println(super.age); //使用父类成员变量
        //System.out.println(super.(super.age));
    }
}

class ExtendsDemo4 {
    public static void main(String[] args) {
        Zi z= new Zi();
        z.method();
    }
}
super关键字:对比this关键字
    this可调用:
        成员变量:this.成员变量
        成员方法:this.成员方法
        构造方法:this(参数)  //调用本类的其他构造方法
    super可以调用:
        成员变量:super.成员变量 //当本类和父类的成员变量重名时,使用“super.成员变量”访问父类的成员变量
        成员方法:super.成员方法  //调用父类的成员方法。
        构造方法:super(参数)  //父类的构造函数

    继承中变量的使用原则:就近原则
    继承中方法的使用原则:就近原则。
class Fu {
    int age = 20;

    public void method(){
        System.out.println("父类的method方法");
    }
}
class Zi extends Fu {
    int age = 18;
    public void test(){
        //System.out.println(this.age);
        //System.out.println(super.age);
        super.method();
    }


    public void method(){
        System.out.println("子类的method方法");
    }

}
class SuperDemo {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.test();
    }
}
super在使用构造方法时:
    1.当我们子类构造方法中不写“super(参数)”,系统会默认添加一个“super()”
    2.super(参数)必须是构造方法的第一行。this(参数)和super(参数)不能同时出现。
    3.避免构造方法之间相互循环调用。
    4.子类之间构造方法不管第一句是this还是super,最终必定有一个构造方法去调用super(参数)
class Fu {
    public Fu(){
        System.out.println("父类的无参");
    }
    public Fu(String s){        
        System.out.println("父类的有参");
    }
}
class Zi extends Fu {
    public Zi(){
        this("");
        System.out.println("子类的无参构造方法");

    }
    public Zi(String s){
        this();
        System.out.println("子类的有参构造方法");
    }
}
class SuperDemo2 {
    public static void main(String[] args) {
        Zi z1 = new Zi();
        System.out.println("-----------------------");
        Zi z2 = new Zi("有参");
    }
}
也就是说,如果我们使用静态成员,不管是使用谁的对象来调用,都相当于 类名.成员
class Fu {
    static String name = "张三丰";
}
class Zi extends Fu {
    public Zi(){
        super();
        name = "张翠山";
    }
}

class SuperDemo4 {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.name = "谢逊";  //z.name 其实相当于 Fu.name

        Fu f = new Fu();
        //f.name; 相当于 Fu.name
        System.out.println(f.name);
    }
}
方法重写:方法覆盖、方法覆写。子类方法把父类方法(隐藏)了。
格式要去:
    方法重写要求:除了访问修饰符、和方法体,其他都必须一样。
方法重写的意义:
    当我们对父类的方法不满意的时候,我们可以使用方法重写,把父类的方法给隐藏掉。
class Fu {
    public void method(){
        System.out.println("给12345这个账户打1W¥");
    }
}
class Zi extends Fu{

    public void method(){
        System.out.println("没钱了,先欠着");
    }

    public void test(){
        method();
    }
}
class OverrideDemo {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.method();
    }
}
class Animal {
    public void eat(){
        System.out.println("素食");
    }
}
class Dog  extends Animal{
    public void eat(){
        System.out.println("骨头");
    }
}

class OverrideDemo2 {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.eat();
    }
}
方法重写的作用:
    1.把父类的方法拿过来,修改掉
    2.扩展父类的功能.

方法重载和方法重写的区别:
    方法重载:
        方法名相同、参数列表不同。
    方法重写:
        访问修饰符,子类的访问修饰符必须大于等于父类的访问修饰符。
        方法体是没有任何要求。
        其他部分必须完全一样。

方法重写:
    private的方法不能被重写。

    public > 默认 > private 
class Animal {
    public void eat(){
        System.out.println("骨头");
    }


    public void test(){}

}
class Dog  extends Animal{
    public void eat(){
        super.eat();
        System.out.println("狗粮");
    }

    public void test(){ }
}

class OverrideDemo3 {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.eat();
    }
}
多态:多种形态。
    猫:(动物、猫科动物、猫、宠物)
    狗:(动物、犬科动物、狗、宠物)
多态的前提:
    1.必须有继承。
    2.有方法重写。(多态的意义)
    3.父类引用指向子类对象。(多态的表现)
class Animal {
    public void say(){

    }

    public void eat(){
        System.out.println("----------------------------");
    }
}

class Dog extends Animal {
    public void say(){
        System.out.println("汪汪");
    }

    public void eat(){
        System.out.println("啃骨头");
    }
}
class DuoTaiDemo {
    public static void main(String[] args) {
        /*
            Animal a = new Animal();
                Animal a:对象的声明,对象的引用。,所以这个叫做 父类的引用。
                new Animal();  //父类对象
                = :指向

            Dog d = new Dog();
                Dog d: //子类的引用
                new Dog(); //子类对象
                = 指向


                父类引用指向子类对象
                    Animal a = new Dog();
        */

        Animal a = new Dog();
        //a.say();
        a.eat();
    }
}
类型转换:
    基本数据类型的转换:
        自动类型转换:小范围转换为大范围。小类型转换为大类型。
            int a = 10;
            double d = a;
        强制类型转换:
            double d = 10.0;
            int a = (int)d;

    引用数据类型可以发生类型转换:
        自动类型转换:子类会自动转换为父类。
            Dog d = new Dog();
            Animal a = d;
        强制类型转换:逻辑上可以转换的类型转换才可以。
            目标类型 变量名 = (目标类型)待转数据
            Dog d1 = (Dog)a;
class Animal {

}

class Dog extends Animal {
    public void kanJia(){
        System.out.println("看家护院");
    }   
}

class Cat extends Animal  {
}
class DuoTaiDemo2 {
    public static void main(String[] args) {
        //Animal a = new Dog();
        //a.kanJia();
        Dog d = new Dog();
        Animal a = d;

        //Dog d1 = (Dog)a;
        Cat c = (Cat)a;
    }
} 
多态的优点”
    1.提高了代码的复用性。
    2.提高了代码的可维护性。
    3.提高了代码的可扩展性。
//自定义一个医生类
class Doctor {
    /*
    //给猫看病
    public void kanBing(Cat c){
        c.say();
    }
    //给狗看病
    public void kanBing(Dog c){
        c.say();
    }
    */  
    //给动物看病
    public void kanBing(Animal c){
        c.say();
    }
}
class Animal {
    public void say(){}
}
class Cat extends Animal {
    public void say(){
        System.out.println("喵喵");
    }
}
class Dog extends Animal {
    public void say(){
        System.out.println("汪汪");
    }
}

class Tiger extends Animal {
    public void say(){
        System.out.println("嗷……");
    }
}

class DoctorTest {
    public static void main(String[] args) {
        Doctor doc = new Doctor();
        //猫
        //Cat c = new Cat();
        //狗
        //Dog c = new Dog();
        /*
            //Animal a = new Cat();
            //Animal a = new Dog();
        */
        Tiger c = new Tiger();
        doc.kanBing(c);
    }
}
多态里边的成员:
    成员变量:不会反生覆盖。使用的时候,使用的父类的属性。
        编译的时候,要看父类,父类有的我们才能用,父类没有的,我们不能使用。
        运行的时候,也看父类。
    成员方法:
    静态成员:
class Animal {
    String classify = "狗";
}


class Dog extends Animal {
    String classify = "藏獒";
}
class DuoTaicybl {
    public static void main(String[] args) {
        //Dog d = new Dog();
        //父类引用指向子类对象
        Animal a = new Dog();
        System.out.println(a.classify);
    }
}
class Cat {
    //String name = "猫";
}

class Dog extends Cat {
    String name = "狗";
}
class DuoTaicybl1 {
    public static void main(String[] args) {
        Cat c = new Dog();
    }
}
多态成员方法:
    编译时:看父类,如果父类没有,我们不能使用。
    运行的时候看子类。

    成员方法和成员变量:
        编译时(写代码的时候):
            成员方法:看父类,父类有的我们才能使用,父类没有,不能使用
            成员变量:看父类,父类有的我们才能使用,父类没有,不能使用
        运行时:
            成员变量:看父类。
            成员方法:看子类。
class Animal {
    public void say(){

    }
}

class Dog extends Animal {
    public void say(){
        System.out.println("汪汪");
    }
}
class DuoTaicyff {
    public static void main(String[] args) {
        Animal a = new Dog();
        a.say();
    }
}
final:最终的,不可改变的。
    可以修饰;类、方法、变量。
        修饰方法时:该方法不允许重写
        修饰类的时候:该类不能被继承。
        修饰变量时:该变量的值不允许修改。(final修饰变量时,变量有个特殊的称呼,叫做“常量”)
            final修饰的成员变量,必须初始化。
class Bank{
    final int a = 10;
    public void balance(String s){
        s = "123456";

        System.out.println("给帐号"+ s +"减少1000元");
    }
}

class Zi extends Bank{
    public void balance(String s){
         System.out.println("给帐号"+ s + "增加10W元");
    }
}

class BankDemo {
    public static void main(String[] args) {
        Bank b = new Bank(); //new Bank();
        b.balance("1");
    }
}
final修饰的变量:
    如果是基本数据类型的变量:不允许修改的是“值”。
    如果是引用数据类型的变量:不允许修改的是“内存地址”
class Something {
    public int addOne(final int x){
        return 1;//++x;
    }

    public void addOne(final Other o) {
        //o.i++;
        o=new Other();
    }
}
class Other {
    int i;
}


class FinalTest {
    public static void main(String[] args) {

    }
}

总结:

继承的优点:
提高了代码的复用性和可维护性。
继承的特点:
1.只支持单继承,可以多层继承。
2.不能部分继承,继承就是全部继承,不继承就一个都不能要。
3.必须体现是is a 的关系。
继承的格式:
class 子类 extends 父类{}

子类的实例化过程:
1.先加载父类
2.加载子类
3.执行子类构造方法(在构造方法第一行,执行父类构造方法)
4.把开辟的空间的内存地址赋值给 “对象的引用”
继承中的构造方法:

super关键字:
调用父类成员。
    成员变量:super.成员变量  //子类和父类的成员变量重名时,使用"super.成员变量"来访问父类的成员变量
    成员方法:super.成员方法  //子类和父类有方法重写时,使用"super.成员方法"来调用父类的成员方法
    构造方法:super(参数);
        1.如果我们在子类构造方法中不写this、super时,系统会默认给我们添加一个super();
        2.super(参数);必须放在子类构造方法中的第一行。(this和super 不能同时出现。)

方法重写:指的子父类拥有相同的方法。
1.private的方法不可以被重写。
2.构造方法不能继承,也不能重写。
3.子类的访问权限一定要大于等于父类的访问权限。
4.除了方法体和访问修饰符,其他必须保持一致。

多态:事物的多种形态。
前提:
    1.必须有继承关系。
    2.必须有方法重写。(多态的意义)
    3.父类引用指向子类对象。(多态的表现)

多态中的成员:
    编译时:都看父类,如果父类没有的,就不能使用。
    运行时:除了成员方法,其他都看父类。成员方法看子类。

final关键字:
可以修饰、类、属性、方法
    修饰类:则该类不能被继承。
    修饰方法:则该方法不能被重写。
    修饰变量:该变量不能改变。(这种不可改变的量称之为"常量")
        修饰成员变量时,该变量必须初始化。
        如果修饰的是基本数据类型的变量,则该变量不可改变的"值"
        如果修饰的是引用数据类型的变量,则该变量不可改变的是"内存地址"

——- android培训java培训、期待与您交流! ———-

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值