java8.0——继承和多态

目录

一,继承

1.什么是继承

2.怎样实现继承

3.父类成员访问

(1)子类中访问父类的成员变量

(2) 子类中访问父类的成员方法

4.super关键字

5.子类构造方法

(1)this和super的区别

6.继承关系上的执行顺序

7.继承的种类

(1)单继承

(2)多层继承

(3)不同类继承同一类

(4)不支持多继承

8.final关键字

(9)组合与继承的区别

二,多态

1.什么是多态

2.多态实现条件

3.向上转型

4.向下转型

5.多态的优缺点

(1)优点

(2)缺点


一,继承

1.什么是继承

1.是一种可以使代码复用的手段,以实现共性的抽取。

2.派生类/子类:在原有类(父类/基类/超类)的基础上进行扩展,以增加新功能。

2.怎样实现继承

使用extends关键字,如

public class TestExtends {
    public static void main(String[] args) {
        Apple apple=new Apple();
        System.out.println(apple.color);//父类的成员变量继承到了子类里
        System.out.println(apple.name);
        System.out.println(apple.kg);
    }
}
 class Fruit{
     String name;
     String color;
}
 class Apple extends Fruit{
     String kg;//仔细想想,如果什么都不添加,那还用继承干嘛?
}

1.父类成员变量继承到了子类里

2.子类必须添加新的部分,体现出与父类的不同

3.父类成员访问

(1)子类中访问父类的成员变量

1. 子类和父类不存在同名成员变量

public class Base {
  int a;
  int b;
}
public class Derived extends Base{
  int c;
  public void method(){
    a = 10;   // 访问从父类中继承下来的a
    b = 20;   // 访问从父类中继承下来的b
    c = 30;   // 访问子类自己的c
 }
}

2. 子类和父类成员变量同名,优先子类

public class Base {
  int a;
  int b;
  int c;
}

public class Level extends Base{
  int a;        // 与父类中成员a同名,且类型相同
  char b;       // 与父类中成员b同名,但类型不同
  public void method(){
    a = 100;     // 子类的a
    b = 101;     // 子类的b
    c = 102;     // 父类的c
 }
}

(2) 子类中访问父类的成员方法

1.成员方法名字相同

参数列表不同则构成重载,参数列表相同访问子类

public class Base {
  public void methodA(){ }

  public void methodB(){ }

}

public class Derived extends Base{

  public void methodA(int a) { }

  public void methodB(){ }

  public void methodC(){
    methodA();    // 没有传参,访问父类中的methodA()
    methodA(20);   // 传递int参数,访问子类中的methodA(int)
    methodB();    // 永远访问子类中的methodB()
 }

}

2.成员方法名字不同

优先访问自己的方法,自己没有时,再到父类中找,如果父类中也没有则报错。

4.super关键字

主要作用:在子父类出现相同名称的成员时,子类方法中访问父类的成员。

【注意】

1. 只能在非静态方法中使用
2. 在子类方法中,访问父类的成员变量和方法。

public class Base {
  int a=1;
  int b=2;
  public void methodB(){

  System.out.println("Base中的methodB()");}

}

public class Derived extends Base{
  int a=3;   // 与父类中成员变量同名且类型相同
  char b=4;  // 与父类中成员变量同名但类型不同

public void methodB(){
  System.out.println("Derived中的methodB()");
}

  public void methodC(){
    a=5;b=6;methodB();//访问的都是子类的

    // 访问父类的成员时,需要借助super关键字
    super.a = 5;
    super.b = 6;
    super.methodB(); //不要忘记"."!
 }
}

5.子类构造方法

新建子类构造方法时,需要先调用基类构造方法,然后再执行子类的构造方法。

public class Base {
  public Base(){
    System.out.println("Base()");
}
}

public class Derived extends Base{
 public Derived(){
   super();  
   // 用户没有写时,编译器会自动添加(必须是无参父类构造方法)
   // super()必须是子类构造方法中第一条语句
   // 只能出现一次
   System.out.println("Derived()");
 }
}

public class Test {
  public static void main(String[] args) {
    Derived d = new Derived();
 }
}

//结果打印:
//Base()
//Derived(

【注意】

1. 若父类定义无参或者默认的构造方法时,在子类构造方法第一行默认super()调用
2. 如果父类构造方法是带有参数的,则不会再给子类生成默认的构造方法,此时需要用户在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现

(1)this和super的区别

【相同点】
1. 都是Java中的关键字
2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在
【不同点】
1. this是当前对象的引用,super是子类对父类部分成员的引用
2. 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类的方法和属性
3. this是非静态成员方法的一个隐藏参数,super不是隐藏的参数
4. 在构造方法中:this(...)用于调用本类构造方法,super(...)用于调用父类构造方法,两种调用不能同时在构造方法中出现
5. 构造方法中一定会存在super(...)的调用,但是this(...)不写则没有

6.继承关系上的执行顺序

第一次实例化子类对象时:

父类静态代码块>子类静态代码>父类实例代码块>父类构造方法>子类的实例代码块>子类构造方法

第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

什么?你忘了什么是代码块?

class Person {
  public String name;
  public int age;

//构造方法
  public Person(String name, int age) {
    this.name = name;
    this.age = age;
    System.out.println("构造方法执行");
 }

//实例代码块
 {
    System.out.println("实例代码块执行");
 }

//静态代码块
  static {
    System.out.println("静态代码块执行");
  }

}

7.继承的种类

(1)单继承

Class A——》Calss B

public class A{}

public class B extends A{}

(2)多层继承

Class A——》Calss B——》Class C(一般不超过3层)

​
public class A{}

public class B extends A{}

​public class C extends B{}

(3)不同类继承同一类

Class B——》Calss A

Class C——》Calss A

​
​
public class A{}

public class B extends A{}

​public class C extends A{}

​

(4)不支持多继承

一个类不能又继承A又继承B,脚踏两条船

8.final关键字

1. 修饰变量或字段,表示常量(不能修改)

final int a = 10;
a = 20;  // 编译出错

2. 修饰类:表示此类不能被继承

final public class Animal {
 ...
}
public class Bird extends Animal {
 ...
}
// 编译出错

3. 修饰方法:表示该方法不能被重写

(9)组合与继承的区别

组合更像是通过部件将一个物体组合起来,而继承则像是小物体与大物体是上下延续关系

// 轮胎类
class Tire{}

// 发动机类
class Engine{}

// 车载系统类
class VehicleSystem{}

class Car{
  private Tire tire;      // 可以复用轮胎中的属性和方法
  private Engine engine;    // 可以复用发动机中的属性和方法
  private VehicleSystem vs;  // 可以复用车载系统中的属性和方法
}

// 奔驰是汽车
class Benz extend Car{
  // 将汽车中包含的:轮胎、发送机、车载系统全部继承下来
}

二,多态

1.什么是多态

当不同的对象去完成同一个事时,产生出的不同状态。

2.多态实现条件

1. 必须在继承体系下
2. 子类必须要对父类中方法进行重写(返回值和形参不做改变,改变方法中的内容)

public class A{

public void eat(){}

}

 重写A中方法eat(),{ }中内容记得改变,这里为了直观体现就不填写内容了

public class C extends A{

 public void eat(){}

}
public class D extends A{

 public void eat(){}

}

【方法重写的规则】
(1)子类在重写父类的方法时,一般必须与父类方法原型一致:修饰符 返回值类型 方法名(参数列表) ,返回值类型可以不同,但必须是有子父类关系
(2)访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected
(3)父类被static、private修饰的方法、构造方法都不能被重写。
(4)重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 


3. 通过父类的引用调用重写的方法

a这个引用调用eat方法的这种行为就称为多态.一次调用,以后将可能会出现c与d两种表现

public static void eat(父类 a){
    a.eat();//这里a调用的不知道是哪个子类,c或是d
 }

4.再在main中使用

 public static void main(String[] args) {
    C c=new C();
    D d=new d();
    
    eat(c);
    eat(d);
 }

3.向上转型

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。

Animal animal = new Cat("元宝",2);
父类类型 对象名= new 子类类型();
public class TestAnimal {
  public static void main(String[] args) {
    // 1. 直接赋值:子类对象赋值给父类对象
    Animal cat = new Cat("元宝",2);  
    Animal dog = new Dog("小七", 1);

    eatFood(cat);
    eatFood(dog);

    Animal animal = buyAnimal("狗");
    animal.eat();

    Animal animal2 = buyAnimal("猫");
    animal2.eat();
 }

  // 2. 方法传参:形参为父类型引用,可以接收任意子类的对象
  public static void eatFood(Animal a){
    a.eat();
 }

  // 3. 作返回值:返回任意子类对象
  public static Animal buyAnimal(String var){
    if("狗" == var){
      return new Dog("狗狗",1);
   }else if("猫" == var){
      return new Cat("猫猫", 1);
   }else{
      return null;
   }
 }

}

向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调用到子类特有的方法。

4.向下转型

将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换。

//向上转型
Animal animal = cat;
cat,mew();//无法编译

//向下转型
cat = (Cat)animal;
cat.mew();//mew()是Cat特有的方法,编译成功

 但向下转型往往是不安全的,万一转换失败,运行时就会抛异常。Java中为了提高向下转型的安全性,引入了 instanceof ,如果该表达式为true,则可以安全转换。

if(animal instanceof Cat){
      cat = (Cat)animal;
      cat.mew();
   }

5.多态的优缺点

(1)优点

1. 能够降低代码的 "圈复杂度", 避免使用大量的 if - else

2. 可扩展能力更强

(2)缺点

1.代码的运行效率降低

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于Java实验三继承多态,我可以为您提供一些基本的知识点和例子。 在Java中,继承是一种重要的面向对象编程概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。子类可以使用父类中的属性和方法,也可以添加自己的属性和方法。多态是指同一种类型的对象,在不同的情况下会表现出不同的行为。在Java中,多态可以通过方法重载和方法重写来实现。 下面是一个简单的例子,演示了如何使用继承多态: ``` // 定义一个动物类 class Animal { public void makeSound() { System.out.println("动物发出声音"); } } // 定义一个狗类,继承自动物类 class Dog extends Animal { @Override public void makeSound() { System.out.println("狗发出汪汪声"); } } // 定义一个猫类,继承自动物类 class Cat extends Animal { @Override public void makeSound() { System.out.println("猫发出喵喵声"); } } // 测试多态 public class Test { public static void main(String[] args) { Animal animal1 = new Dog(); Animal animal2 = new Cat(); animal1.makeSound(); // 输出:狗发出汪汪声 animal2.makeSound(); // 输出:猫发出喵喵声 } } ``` 在上面的例子中,我们定义了一个Animal类,它有一个makeSound()方法。然后我们定义了一个Dog类和一个Cat类,它们都继承自Animal类,并重写了makeSound()方法。最后,在测试类中,我们创建了一个Animal类型的变量animal1和animal2,分别指向Dog对象和Cat对象。由于多态的特性,animal1和animal2都可以调用makeSound()方法,但是它们实际上调用的是Dog类和Cat类中重写的makeSound()方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值