重生之我是Java小白三

一.继承

1.相关概念

1.1继承概念

java针对多个类中有相同的部分的话,可以将相同的部分提取出来,单独放到一个类中A, 然后其他类与这个A类产生一个关系,这样的话 其他类中就拥有了A类中的属性或者行为。这个关系叫做继承, java提供了一个关键字 extends来表示继承关系

1.2子类与父类

类在继承关系中称之为子类/派生类,父类在继承关系中称之为父类/基类/超类

1.3继承的好处

1.提高了代码的复用性:多个类相同的成员可以放到同一个类中

2.提高了代码的维护性:如果功能的代码需要修改,修改一处即可

3.让类与类之间产生了关系,是多态的前提:其实这也是继承的一个弊端:类的耦合性很强

1.4相关格式

class 子类类名 extends 父类名

package com.shujia.day7;
class Person{
    String name;
    int age;
    public void study(){
        System.out.println("学习");
    }
    public void eat(){
        System.out.println("吃饭");
    }
}
class Student extends Person{

}

public class ExtendsDemo1 {
    public static void main(String[] args) {
        Student student = new Student();
        student.study();
        student.eat();
    }
}
/*运行结果
学习
吃饭

 */

2.继承的特点

2.1子类无法继承父类的构造方法

package com.shujia.day7;
class Person1{
    String name;
    int age;

    public Person1() {
    }

    public Person1(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void study(){
        System.out.println("学习");
    }
    public void eat(){
        System.out.println("吃饭");
    }
}
//创建子类
class Student2 extends Person1{

}
public class ExtendsDemo2 {
    public static void main(String[] args) {
//        Student2 student2 = new Student2("NAME",18);报错原因是子类无法继承父类的构造方法
    }
}

子类可以自己添加自己的构造方法

package com.shujia.day7;
class Person1{
    String name;
    int age;

    public Person1() {
    }

    public Person1(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void study(){
        System.out.println("学习");
    }
    public void eat(){
        System.out.println("吃饭");
    }
}
//创建子类
class Student1 extends Person1{
    public Student1() {
    }

    public Student1(String name, int age) {
        this.name=name;
        this.age=age;
    }
}
public class ExtendsDemo2 {
    public static void main(String[] args) {
//        Student2 student2 = new Student2("NAME",18);报错原因是子类无法继承父类的构造方法
        Student1 student1 = new Student1("kkk",18);//这样可以的原因是子类自己写了自己的构造方法
    }
}

2.2无法多继承,只允许单继承

一个子类无法同时继承2个类 例如

class Zi extends Fu,Mu    这样会报错的

2.3允许多重继承

例如 

class Ye

class Fu extends Ye

class Zi extends Fu

2.4子类无法继承父类的私有变量以及私有方法

package com.shujia.day7;
class Fu{
    //定义成员变量
    String name="qq";
    private int age=10;

    //定义成员方法
    public void fun1(){
        System.out.println("aaaaa");
    }
    private void fun2(){
        System.out.println("bbbbb");
    }
}
class Zi extends Fu{

}
public class ExtendsDemo3 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println(zi.name);
//        System.out.println(zi.age); 子类无法继承父类的private变量
        zi.fun1();
//        zi.fun2()   子类无法继承父类的私有方法
    }
}
/*
运行结果
qq
aaaaa
 */

3.继承与成员变量的关系

3.1.就近原则

首先在子类局部范围找

然后在子类成员范围找

最后在父类成员范围找(肯定不能访问到父类局部范围)(且不能访问父类中方法的局部变量)

如果还是没有就报错。(不考虑父亲的父亲…)

package com.shujia.day7;
class Fu1{
    int a=10;

}
class Zi1 extends Fu1{
    int a=20;
    public void show1(){
        int a=30;
        System.out.println(a);
    }

}
public class ExtendsDemo4 {
    public static void main(String[] args) {
        Zi1 zi1 = new Zi1();
        zi1.show1();
    }
}

3.2.获取子类的成员变量

this.子类成员变量名

package com.shujia.day7;
class Fu1{
    //定义父类的成员变量
    int a=10;

}
class Zi1 extends Fu1{
    //定义子类的成员变量
    int a=20;
    public void show1(){
        //定义子类的局部变量
        int a=30;
        System.out.println(a); //打印局部变量
        System.out.println(this.a);//打印子类的成员变量
        System.out.println(super.a);//打印父类的成员变量
    }

}
public class ExtendsDemo4 {
    public static void main(String[] args) {
        Zi1 zi1 = new Zi1();
        zi1.show1();
    }
}

3.3获取父类成员变量

super.父类成员变量名

package com.shujia.day7;
class Fu1{
    //定义父类的成员变量
    int a=10;

}
class Zi1 extends Fu1{
    //定义子类的成员变量
    int a=20;
    public void show1(){
        //定义子类的局部变量
        int a=30;
        System.out.println(a); //打印局部变量
        System.out.println(this.a);//打印子类的成员变量
        System.out.println(super.a);//打印父类的成员变量
    }

}
public class ExtendsDemo4 {
    public static void main(String[] args) {
        Zi1 zi1 = new Zi1();
        zi1.show1();
    }
}

3.4使用父类的私有成员变量

1.全是私有变量

1.在父类中创建对应属性的set以及get方法还有show方法(因为show方法不是私有的,但是里面展示的是私有成员),然后在测试类中创建子类,再通过子类名.set方法赋值,再通过show方法输出

2.父类中的有参构造方法,在子类中调用,传入的是父类的私有变量(这里的变量不是继承,只是使用),然后在测试类中创建子类,通过有参传值即可

package com.shujia.day7;

//定义父类
class Fu3{

    //定义私有成员
    private String name;
    private int age;

    //定义构造无参方法
    public Fu3() {
    }

    //定义有参构造方法

    public Fu3(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //定义set以及get方法

    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;
    }

    //定义show方法,主要是用来展示成员变量
    public void show(){
        System.out.println("姓名是:"+this.name);
        System.out.println("年龄是:"+this.age);
    }
}

//定义子类
class Zi3 extends Fu3{
    //调用父类的构造方法

    //创建子类无参构造方法
    public Zi3() {
    }

    //创建子类有参调用方法
    public Zi3(String name, int age) {
        super(name, age);
    }
}

//定义测试类
public class ExtendsDemo6 {
    public static void main(String[] args) {
        //测试Fu3类
        //创建Fu3对象
        Fu3 fu3D1 = new Fu3();
//
//        //无参传值
        fu3D1.setAge(18);
        fu3D1.setName("黄大大");
        fu3D1.show();

        //有参传值
        Fu3 fu3D2 = new Fu3("黄大大", 18);
        fu3D2.show();

        //测试Zi3类
        //创建Zi3对象
        Zi3 zi3D3 = new Zi3();

        //无参传值
        //通过父类的set以及get方法使用父类的私有变量
        zi3D3.setName("黄大大");
        zi3D3.setAge(18);
        zi3D3.show();

        //有参传值
        Zi3 zi3D4 = new Zi3("黄大大", 18);
        zi3D4.show();
    }
}
/*
姓名是:黄大大
年龄是:18
姓名是:黄大大
年龄是:18
姓名是:黄大大
年龄是:18
姓名是:黄大大
年龄是:18
 */
2.混合型
package com.shujia.day7;

//定义父类
class Fu3{

    //定义私有成员
    private String name;
    private int age;
    int id;

    //定义构造无参方法
    public Fu3() {
    }

    //定义有参构造方法

    public Fu3(String name, int age,int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

    //定义set以及get方法

    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 int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    //定义show方法,主要是用来展示成员变量
    public void show(){
        System.out.println("姓名是:"+this.name);
        System.out.println("年龄是:"+this.age);
        System.out.println("id是:"+this.id);
    }
}

//定义子类
class Zi3 extends Fu3{
    //调用父类的构造方法

    //创建子类无参构造方法
    public Zi3() {
    }
   
   
    //创建子类有参调用方法
    public Zi3(String name, int age,int id) {
        super(name, age,id);
    }
}

//定义测试类
public class ExtendsDemo6 {
    public static void main(String[] args) {
        //测试Fu3类
        //创建Fu3对象
        Fu3 fu3D1 = new Fu3();
//
//        //无参传值
        fu3D1.setAge(18);
        fu3D1.setName("黄大大");
        fu3D1.setId(1001);
        fu3D1.show();

        //有参传值
        Fu3 fu3D2 = new Fu3("黄大大", 18,1001);
        fu3D2.show();

        //测试Zi3类
        //创建Zi3对象
        Zi3 zi3D3 = new Zi3();

        //无参传值
        //通过父类的set以及get方法使用父类的私有变量
        zi3D3.setName("黄大大");
        zi3D3.setAge(18);
        zi3D3.setId(1001);
        zi3D3.show();


        //有参传值
        Zi3 zi3D4 = new Zi3("黄大大", 18,1001);
        zi3D4.show();
    }
}
/*
姓名是:黄大大
年龄是:18
id是:1001
姓名是:黄大大
年龄是:18
id是:1001
姓名是:黄大大
年龄是:18
id是:1001
姓名是:黄大大
年龄是:18
id是:1001
 */

4继承与构造方法的关系

4.1.子类默认第一句话有super()  (直接初始化父类)

默认调用的是父类的无参构造方法


package com.shujia.day7;
class Fu2{
    public Fu2() {
        System.out.println("这是父类的构造方法");
    }
//定义父类的构造方法


}
class Zi3 extends Fu2{

    public Zi3() {
//        super();  默认是第一句话
        System.out.println("这是子类的构造方法");
    }
}
public class ExtendsDemo5 {
    public static void main(String[] args) {
        Zi3 zi3 = new Zi3();

    }
}

这是父类的构造方法
这是子类的构造方法


想调用有参构造方法直接写


package com.shujia.day7;
class Fu2{
    //定义父类的构造方法
    public Fu2() {
        System.out.println("这是父类的构造方法");
    }
    //定义父类的有参构造方法
    public Fu2(String s){
        System.out.println("这是父类的有参构造方法"+s);
    }


}
class Zi3 extends Fu2{

    public Zi3() {
//        super();  默认是第一句话
        //调用父类的有参构造方法
        super("黄大大");
        System.out.println("这是子类的构造方法");
    }
}
public class ExtendsDemo5 {
    public static void main(String[] args) {
        Zi3 zi3 = new Zi3();

    }
}
/*
这是父类的有参构造方法黄大大
这是子类的构造方法
 */



4.2.间接初始化父类


package com.shujia.day7;
class Fu2{
    //定义父类的构造方法
    public Fu2() {
        System.out.println("这是父类的构造方法");
    }
    //定义父类的有参构造方法
    public Fu2(String s){
        System.out.println("这是父类的有参构造方法"+s);
    }


}
class Zi3 extends Fu2{

    public Zi3() {
        this("黄大大");
        System.out.println("这是子类的构造方法");
    }
    public Zi3(String s){
        super(s);
    }
}
public class ExtendsDemo5 {
    public static void main(String[] args) {
        Zi3 zi3 = new Zi3();
    }
}
/*
这是父类的有参构造方法黄大大
这是子类的构造方法
 */



super(…)或者this(….)必须出现在第一条语句

5.继承与成员方法的关系

5.1也遵循就近原则

package com.shujia.day7;
class Fu4{
    //定义父类的成员方法
    public void fun1(){
        System.out.println("打游戏");
    }
}
class Zi4 extends Fu4{
    //定义子类的成员方法或者说重写父类方法fun1
    public void fun1(){
        System.out.println("打王者");
    }
}

public class ExtendsDemo7 {
    public static void main(String[] args) {
        Zi4 zi4 = new Zi4();
        zi4.fun1();
    }
}
/*
打王者
 */

5.2子类使用父类的私有方法

在父类中定义一个公有方法来调用父类的私有方法,然后在子类中直接调用这个公有方法

package com.shujia.day7;

//定义父类
class Fu3{

    //定义私有成员
    private String name;
    private int age;
    int id;

    //定义构造无参方法
    public Fu3() {
    }

    //定义有参构造方法

    public Fu3(String name, int age,int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

    //定义set以及get方法

    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 int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    //定义父类私有方法
    private void fun(){
        System.out.println("这是父类的私有方法");
    }

    //普通方法,直接在父类中调用父类的私有方法
    public void fun1(){
        fun();
    }


    //定义show方法,主要是用来展示成员变量
    public void show(){
        System.out.println("姓名是:"+this.name);
        System.out.println("年龄是:"+this.age);
        System.out.println("id是:"+this.id);
    }
}

//定义子类
class Zi3 extends Fu3{
    //调用父类的构造方法

    //创建子类无参构造方法
    public Zi3() {
    }


    //创建子类有参调用方法
    public Zi3(String name, int age,int id) {
        super(name, age,id);
    }
}

//定义测试类
public class ExtendsDemo6 {
    public static void main(String[] args) {
        //测试Fu3类
        //创建Fu3对象
        Fu3 fu3D1 = new Fu3();
//
//        //无参传值
        fu3D1.setAge(18);
        fu3D1.setName("黄大大");
        fu3D1.setId(1001);
        fu3D1.show();

        //有参传值
        Fu3 fu3D2 = new Fu3("黄大大", 18,1001);
        fu3D2.show();

        //测试Zi3类
        //创建Zi3对象
        Zi3 zi3D3 = new Zi3();

        //无参传值
        //通过父类的set以及get方法使用父类的私有变量
        zi3D3.setName("黄大大");
        zi3D3.setAge(18);
        zi3D3.setId(1001);
        zi3D3.show();


        //有参传值
        Zi3 zi3D4 = new Zi3("黄大大", 18,1001);
        zi3D4.show();
        zi3D4.fun1();

    }
}
/*
姓名是:黄大大
年龄是:18
id是:1001
姓名是:黄大大
年龄是:18
id是:1001
姓名是:黄大大
年龄是:18
id是:1001
姓名是:黄大大
年龄是:18
id是:1001
这是父类的私有方法
 */

6.方法的重写

6.1概念

子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写

6.2使用

1.用@override检测是否能重写
package com.shujia.day7;
class Fu4{
    //定义父类的成员方法
    public void fun1(){
        System.out.println("打游戏");
    }
}
class Zi4 extends Fu4{
    //定义子类的成员方法或者说重写父类方法fun1
    @Override
    public void fun1(){
        System.out.println("打王者");
    }
}

public class ExtendsDemo7 {
    public static void main(String[] args) {
        Zi4 zi4 = new Zi4();
        zi4.fun1();
    }
}
/*
打王者
 */
2.无法重写父类的私有成员方法
package com.shujia.day7;
class Fu4{
    //定义父类的成员方法
    public void fun1(){
        System.out.println("打游戏");
    }
    //定义父类私有的成员方法
    private void fun2(){
        System.out.println("听歌");
    }
}
class Zi4 extends Fu4{
    //定义子类的成员方法或者说重写父类方法fun1
    @Override
    public void fun1(){
        System.out.println("打王者");
    }
//    @Override
//    private void fun2(){
//        System.out.println("听周杰伦");
//    } 报错原因是无法重写父类的私有成员方法
}

public class ExtendsDemo7 {
    public static void main(String[] args) {
        Zi4 zi4 = new Zi4();
        zi4.fun1();
//        zi4.fun2();  报错原因是无法重写父类的私有成员方法
    }
}
/*
打王者
 */
3.可以重写比父类方法修饰符大于等于的修饰符

public>protected>默认>private

package com.shujia.day7;
class Fu4{
    //定义父类的成员方法
    public void fun1(){
        System.out.println("打游戏");
    }
    //定义父类私有的成员方法
    private void fun2(){
        System.out.println("听歌");
    }
    //定义父类的成员方法被默认修饰符修饰
    void fun3(){
        System.out.println("看小说");
    }
}
class Zi4 extends Fu4{
    //定义子类的成员方法或者说重写父类方法fun1
    @Override
    public void fun1(){
        System.out.println("打王者");
    }
    //重写父类的fun2
//    @Override
//    private void fun2(){
//        System.out.println("听周杰伦");
//    } 报错原因是无法重写父类的私有成员方法

    //重写父类的fun3
    @Override
    void fun3(){
        System.out.println("看斗破苍穹");
    }
}

public class ExtendsDemo7 {
    public static void main(String[] args) {
        Zi4 zi4 = new Zi4();
        zi4.fun1();
//        zi4.fun2();  报错原因是无法重写父类的私有成员方法
        zi4.fun3();
    }
}
/*
打王者
看斗破苍穹
 */
4.无法重写父类的静态方法,但是可以使用
package com.shujia.day7;
class Fu4{
    //定义父类的成员方法
    public void fun1(){
        System.out.println("打游戏");
    }
    //定义父类私有的成员方法
    private void fun2(){
        System.out.println("听歌");
    }
    //定义父类的成员方法被默认修饰符修饰
    void fun3(){
        System.out.println("看小说");
    }
    //定义父类的静态方法
    public static void fun4(){
        System.out.println("这是父类的静态方法");
    }
}
class Zi4 extends Fu4{
    //定义子类的成员方法或者说重写父类方法fun1
    @Override
    public void fun1(){
        System.out.println("打王者");
    }
    //重写父类的fun2
//    @Override
//    private void fun2(){
//        System.out.println("听周杰伦");
//    } 报错原因是无法重写父类的私有成员方法

    //重写父类的fun3
    @Override
    void fun3(){
        System.out.println("看斗破苍穹");
    }
    //定义子类的静态方法
//    @Override
//    public static void fun4(){
//        System.out.println("这是子类的静态方法");
//    }//报错原因是子类无法重写父类的静态方法
}

public class ExtendsDemo7 {
    public static void main(String[] args) {
        Zi4 zi4 = new Zi4();
        zi4.fun1();
//        zi4.fun2();  报错原因是无法重写父类的私有成员方法
        zi4.fun3();
        zi4.fun4();  //这里可以使用父类的静态方法
    }
}
/*
打王者
看斗破苍穹
这是父类的静态方法
 */

6.3重写与重载的区别

1、重载是发生在同一个类中的,方法名相同,参数列表不同,与返回值无关的现象

2、重写是发生在继承关系中的,返回值类型,方法名,参数列表都和父类一模一样,只是实现不一样,使用 @Override检测方法能否重写

7.final关键字

7.1类被修饰

不能被继承

7.2引用数据变量被修饰

变量变常量

package com.shujia.day7;
class Final{
    int a=10;
    final int b=20;
}
class FinalZi extends Final{
    public void show(){
        a=100;
//        b=200;  报错的原因是b前面有fianl修饰,变常量,不能被修改
        System.out.println(a);
        System.out.println(b);
    }
}
public class FinalDemo1 {
    public static void main(String[] args) {
        FinalZi finalZi = new FinalZi();
        finalZi.show();
    }
}
/*
100
20
 */

7.3方法被修饰

不能被重写但是可以使用

package com.shujia.day7;
class Fu5{
    //定义父类的show1方法
    public void show1(){
        System.out.println("这是父类的show1方法");
    }
    //定义父类的被final修饰的show2方法
    public final void show2(){
        System.out.println("这是父类的被final修饰的show2方法" );
    }
}
class Zi5 extends Fu5{
    @Override
    public void show1(){
        System.out.println("这是子类的重写show1方法");
    }
//    @Override
//    public final void show2(){
//        System.out.println("这是子类的重写show1方法");
//    }报错是因为 被final修饰的父类成员方法无法被重写
}

public class FinalDemo2 {
    public static void main(String[] args) {
        Zi5 zi5 = new Zi5();
        zi5.show1();
        zi5.show2();//不能被重写,但是可以使用
    }
}
/*
这是子类的重写show1方法
这是父类的被final修饰的show2方法

 */

7.4对象被修饰

可以修改一次不是被final修饰的变量

package com.shujia.day7;
class Demo1{
    int a=10;
}
public class FinalDemo3 {
    public static void main(String[] args) {
        final Demo1 demo1 = new Demo1();
        demo1.a=100;
        System.out.println(demo1.a);
    }
}
/*
100
 */

7.5注意事项

1.被final修饰的变量,必须要手动赋值之后才能使用,并且只能赋值一次

package com.shujia.day7;
class Demo2{
    int a=2;
//    final int b;  报错的原因被fianl修饰的变量必须手动赋值才能使用
}
public class FinalDemo4 {
}

2.必须在构造方法结束之前手动赋值

a.使用构造代码块进行赋值

package com.shujia.day7;
class Demo2{
    int a=2;
//    final int b;  报错的原因被fianl修饰的变量必须手动赋值才能使用
    final int b;
//    使用代码块手动赋值
    {
        b=100;
    }
}
public class FinalDemo4 {
    public static void main(String[] args) {
        Demo2 demo2 = new Demo2();
        System.out.println(demo2.b);
    }
}

b.在构造方法内部进行赋值

package com.shujia.day7;

class Demo2 {
    int a = 2;
    //    final int b;  报错的原因被fianl修饰的变量必须手动赋值才能使用
    final int b;
//构造方法赋值
     Demo2() {
        b=200;
    }
}

public class FinalDemo4 {
    public static void main(String[] args) {
        Demo2 demo2 = new Demo2();
        System.out.println(demo2.b);
    }
}

8继承里面的代码块

1.首先初始化父类的静态代码块,再是子类的静态代码块

2.再是父类的构造代码块,再是父类的构造方法

3.再是子类的构造代码块,再是子类的构造方法

二.多态

1.相关概念

1.1什么是多态

某一个事物,在不同时刻表现出来的不同状态。

1.2多态的前提

1.有继承关系     

2.有方法重写 

3.有父类引用指向子类对象

1.3相关格式

父类名 变量名 =new 子类名();

package com.shujia.day7;
//创建父类
class Water{
    
    //创建父类成员方法
    public void drink(){
        System.out.println("水可以喝");
    }
}

//创建子类
class GuTaiWater extends Water{
    
    //重写父类方法
    @Override
    public void drink(){
        System.out.println("固态水也可以喝");
    }
}

public class DuoTaiDemo1 {
    public static void main(String[] args) {
        //父类的引用指向子类对象
        Water water=new GuTaiWater();
        water.drink();
    }
}
/*
固态水也可以喝
 */

2.多态访问成员的特点

2.1成员变量

编译看左边,运行看左边

package com.shujia.day7;
class Fu6{
    int a=10;
    public void show1(){
        System.out.println("黄大大");
    }
    public static void show2(){
        System.out.println("hello");
    }
}
class Zi6 extends Fu6{
    int a=20;
    @Override
    public void show1(){
        System.out.println("郑心怡");
    }
    public static void show2(){
        System.out.println("java");
    }
}

public class DuoTaiDemo2 {
    public static void main(String[] args) {
        Fu6 fu6=new Zi6();
        System.out.println(fu6.a);

        fu6.show1();

        fu6.show2();
    }
}
/*
10  原因是编译看左边,先去找Fu6中有没有a这个变量,如果有那么编译不报错,再去Fu6中寻找a的变量,输出a
郑心怡   原因是编译看左边,先去找Fu6中有没有show1这个方法,如果有那么编译不报错,再去Zi6中show1这个方法,
hello   原因是编译看左边,先去找Fu6中有没有show2这个方法,如果有那么编译不报错,再去Fu6中show1这个方法,
 */

2.2成员方法

编译看左,编译看右

package com.shujia.day7;
class Fu6{
    int a=10;
    public void show1(){
        System.out.println("黄大大");
    }
    public static void show2(){
        System.out.println("hello");
    }
}
class Zi6 extends Fu6{
    int a=20;
    @Override
    public void show1(){
        System.out.println("郑心怡");
    }
    public static void show2(){
        System.out.println("java");
    }
}

public class DuoTaiDemo2 {
    public static void main(String[] args) {
        Fu6 fu6=new Zi6();
        System.out.println(fu6.a);

        fu6.show1();

        fu6.show2();
    }
}
/*
10  原因是编译看左边,先去找Fu6中有没有a这个变量,如果有那么编译不报错,再去Fu6中寻找a的变量,输出a
郑心怡   原因是编译看左边,先去找Fu6中有没有show1这个方法,如果有那么编译不报错,再去Zi6中show1这个方法,
hello   原因是编译看左边,先去找Fu6中有没有show2这个方法,如果有那么编译不报错,再去Fu6中show1这个方法,
 */

2.3静态方法

编译看左边,运行看左边

package com.shujia.day7;
class Fu6{
    int a=10;
    public void show1(){
        System.out.println("黄大大");
    }
    public static void show2(){
        System.out.println("hello");
    }
}
class Zi6 extends Fu6{
    int a=20;
    @Override
    public void show1(){
        System.out.println("郑心怡");
    }
    public static void show2(){
        System.out.println("java");
    }
}

public class DuoTaiDemo2 {
    public static void main(String[] args) {
        Fu6 fu6=new Zi6();
        System.out.println(fu6.a);

        fu6.show1();

        fu6.show2();
    }
}
/*
10  原因是编译看左边,先去找Fu6中有没有a这个变量,如果有那么编译不报错,再去Fu6中寻找a的变量,输出a
郑心怡   原因是编译看左边,先去找Fu6中有没有show1这个方法,如果有那么编译不报错,再去Zi6中show1这个方法,
hello   原因是编译看左边,先去找Fu6中有没有show2这个方法,如果有那么编译不报错,再去Fu6中show1这个方法,
 */

2.4例题

package com.shujia.day7;
class A
{
    public void show()
    {
        show2();
    }

    public void show2()
    {
        System.out.println("我");
    }
}
class B extends A
{
    public void show2()
    {
        System.out.println("爱");
    }
}
class C extends B
{
    public void show()
    {
        super.show();
    }

    public void show2()
    {
        System.out.println("你");
    }
}

public class TextDemo1 {
    public static void main(String[] args) {
        A a = new B();
        a.show();

        B b = new C();
        b.show();

    }
}
/*
爱
分析原因:类A中有show方法,所以编译不报错,运行看右。类B中直接继承了类A的show方法,然后调用类B的show2方法,打印 爱
你
分析原因:类B中有继承类A的show方法,所以不报错,运行看右。类C中的show方法直接调用类B的show方法,,而类B的show方法也是调用show2方法,这个调用是就近原则所以打印你
 */

3.多态的好处

3.1提高了程序的扩展性

1.不用多态

package com.shujia.day8;

//创建父类Animal
class Animal{

    //创建父类成员变量
    String name;
    int age;

    //创建父类无参构造方法
    public Animal() {
    }

    //创建父类有参构造方法
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //创建父类成员方法
    public void eat(){
        System.out.println("吃");
    }

    //创建父类成员方法
    public void sleep(){
        System.out.println("睡");
    }
}

//创建子类
class Tiger extends Animal {

    //创建子类的无参构造方法
    public Tiger() {
    }

    //创建子类的有参构造方法
    public Tiger(String name, int age) {
        super(name, age);
    }

    //重写父类eat方法
    @Override
    public void eat(){
        System.out.println("🐅吃🥩");
    }

    //重写父类sleep方法
    @Override
    public void sleep(){
        System.out.println("🐅趴着睡");
    }

    class Bear extends Animal{
        public Bear() {
        }

        public Bear(String name, int age) {
            super(name, age);
        }

        @Override
        public void eat() {
            System.out.println("🐻吃🐅");
        }

        @Override
        public void sleep() {
            System.out.println("🐻侧着睡");
        }
    }
}


class Bear extends Animal{
    public Bear() {
    }

    public Bear(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("🐻吃🐅");
    }

    @Override
    public void sleep() {
        System.out.println("🐻侧着睡");
    }
}
public class DuoTaiDemo1 {
    public static void main(String[] args) {

        //创建虎1对象
        Tiger tiger1 = new Tiger("虎大", 2);
        tiger1.eat();
        tiger1.sleep();
      
     
//        //创建虎2对象
        Tiger tiger2 = new Tiger("虎二", 1);
        tiger2.eat();
        tiger2.sleep();

       //创建熊1对象
        Bear bear1 = new Bear("熊大", 5);
        bear1.eat();
        bear1.sleep();

//        //创建熊2对象
        Bear bear2 = new Bear("熊二", 3);
        bear2.eat();
        bear2.sleep();

    }

}

/*
🐅吃🥩
🐅趴着睡
🐅吃🥩
🐅趴着睡
🐻吃🐅
🐻侧着睡
🐻吃🐅
🐻侧着睡
 */

2.用多态

package com.shujia.day8;

//创建父类Animal
class Animal{

    //创建父类成员变量
    String name;
    int age;

    //创建父类无参构造方法
    public Animal() {
    }

    //创建父类有参构造方法
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //创建父类成员方法
    public void eat(){
        System.out.println("吃");
    }

    //创建父类成员方法
    public void sleep(){
        System.out.println("睡");
    }
}

//创建子类
class Tiger extends Animal {

    //创建子类的无参构造方法
    public Tiger() {
    }

    //创建子类的有参构造方法
    public Tiger(String name, int age) {
        super(name, age);
    }

    //重写父类eat方法
    @Override
    public void eat(){
        System.out.println("🐅吃🥩");
    }

    //重写父类sleep方法
    @Override
    public void sleep(){
        System.out.println("🐅趴着睡");
    }

    class Bear extends Animal{
        public Bear() {
        }

        public Bear(String name, int age) {
            super(name, age);
        }

        @Override
        public void eat() {
            System.out.println("🐻吃🐅");
        }

        @Override
        public void sleep() {
            System.out.println("🐻侧着睡");
        }
    }
}


class Bear extends Animal{
    public Bear() {
    }

    public Bear(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("🐻吃🐅");
    }

    @Override
    public void sleep() {
        System.out.println("🐻侧着睡");
    }
}

//创建工具类
class AnimalTool{
    /*
        1、构造方法私有化
        2、成员方法必须是静态的
     */
    public static void useAnimal(Animal animal){  //这里相当于 Animal animal=new Tiger("虎大", 2);编译看左,Animal类中有eat方法,编译不报错,运行看右,Tiger类的eat方法
        animal.eat();
        animal.sleep();
    }
}
public class DuoTaiDemo1 {
    public static void main(String[] args) {

        //创建虎1对象
        Tiger tiger1 = new Tiger("虎大", 2);

        //调用工具类的useAnimal方法,传入的是Animal类的对象tiger1
        AnimalTool.useAnimal(tiger1);

        //创建虎2对象
        Tiger tiger2 = new Tiger("虎二", 1);

        //调用工具类的useAnimal方法,传入的是Animal类的对象tiger2
        AnimalTool.useAnimal(tiger2);


       //创建熊1对象
        Bear bear1 = new Bear("熊大", 5);

        //调用工具类的useAnimal方法,传入的是Animal类的对象bear1
        AnimalTool.useAnimal(bear1);


       //创建熊2对象
        Bear bear2 = new Bear("熊二", 3);

        //调用工具类的useAnimal方法,传入的是Animal类的对象bear2
        AnimalTool.useAnimal(bear2);

    }
}
/*
🐅吃🥩
🐅趴着睡
🐅吃🥩
🐅趴着睡
🐻吃🐅
🐻侧着睡
🐻吃🐅
🐻侧着睡
 */

3.2提高了程序的维护性

1.通过继承保证,因为想修改直接去父类的成员方法修改

4.多态的转型

4.1向下转型

1.使用向下转型的原因

不能访问子类特有功能

2.多态变成子类引用指向子类本身的对象
package com.shujia.day8;

//定义父类
class Fu{

    //定义父类的成员方法
    public void fun1(){
        System.out.println("这是父类中的方法fun1");
    }
}

//定义子类
class Zi extends Fu{

    //重写父类的fun1方法
    @Override
    public void fun1(){
        System.out.println("这是重写后的fun1方法");
    }

    //定义子类自己的成员方法
    public void show1(){
        System.out.println("hello world");
    }

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

        //父类的引用指向子类对象
        Fu fu=new Zi();
        fu.fun1();
//        fu.show(); 报错原因是使用多态过后,不能访问子类的方法
        
        //子类的引用指向子类对象
        Zi zi=new Zi();
        zi.show1();
    }
}
/*
这是重写后的fun1方法
hello world

 */

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值