java类和对象:继承、多态、接口、抽象类-2

简介: java类和对象:继承、多态、接口、抽象类

java类和对象:继承、多态、接口、抽象类-1

https://developer.aliyun.com/article/1515765


二、多态

          对于几个不同的类,可以根据他们共同特性,将其抽取出来形成一个共同的父类,这个父类中包含了其他类所具有的共同属性,例如这里有一个狗类,一个猫类,和一个鸟类,他们都有眼睛,都有脚,还可以拥有自己的名字等等静态属性,动态属性,就比如都会吃,喝跑等。


       但是对于不同的动物来说,比如狗和鸟,他们的跑这个行为是不一样的,对于狗来说是用四条腿来跑,而对于鸟来说,只能用两个脚跳,或者用两个翅膀飞,这个行为和狗对比起来是完全不一样的,那么对于其继承的父类来说,不可能只用父类的方法,来描述两个不同的行为,这些行为都是他们的独自的特性。


       这个时候就只需要对其父类的这个方法于子类中进行重写,而不用在每一个子类都实现一个方法,于是就避免了大量重复的代码的编写。同时只需要实例化一个继承这个父类的子类对象,即可调佣相应的方法。

class Animal{
    public void action(){
        System.out.println("正在跑");
    }
}
class Dog extends Animal{
    public void action(){
        System.out.println("正在用四条腿跑");
    }
}
class Bird extends Animal{
    public void fly(){
        System.out.println("正在飞");
    }
}


例如这里有一个Animal父类,其中一个Dog类和Bird类继承这个Animal类。父类中有action这个方法,但是对于鸟和狗来说,他们的行为是不一样的,比如狗是用四条腿跑,而鸟是用翅膀飞。

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Bird bird = new Bird();
        dog.action();
        bird.action();
    }
}


结果如下:

三、抽象类


       有时候我们在实例化对象的时候,难免会将一个父类不小心给实例化了,但是有的情况是不允许父类被实例化的。例如一个父类Animal动物类,他被他的子类Dog继承。我们可以将Dog实例化成一个具体的dog,但是你并不能将一个动物给具体抽象出来,一个动物直接抽象出来会是什么?怎么归类?但是我们又只需要实例化子类对象,而不是父类对象。这就是一大麻烦,为了避免这个问题,我们需要将这个父类设置为抽象类,来避免父类被实例化。


       在实际解决问题的时候,通常将父类设置为抽象类,然后对这个父类进行继承和多态处理,继承关系中,越是在上方的类越抽象,例如狗类继承哺乳类,哺乳类继承动物类等。


       抽象类的语法如下:


public abstract class Test类名{        


       abstract void function( );


}


       abstract为定义抽象类关键字,使用abstract关键字定义的类为抽象类,而使用这个关键字定义的方法被称为抽象方法,这个方法不能有方法体,方法本身没有任何意义,它的作用只存在于被子类重写后。一个类如果有抽象方法,那么他必须被定义为抽象类(如果声明一个抽象方法,就必须将含有这个抽象方法的类定义为抽象类),实际上抽象类除了被继承之外没有任何意义,抽象类同时也保证了类在被继承的时候的安全性。


       对于继承这个抽象类的子类来说,子类需要重写这个抽象类中的所有的抽象方法。


四、接口类

       举一个很简单的例子,一个父类中存在属性:名字,年龄行为:跑,游泳(两个都是抽象方法);


然后我们定一个狗类(假设不会游泳),和一个鱼类都继承这个父类,那么对于狗类和鱼类来说都需要实现跑和游泳这两抽象方法,那么问题来了,狗如何去实现游泳这个方法?那么鱼又如何去实现跑这个方法?鱼不可能会跑,狗不能游泳,或者说狗类不用重写和实现这个方法,那么这个抽象方法是不可能被实现的,但是需要继承这个父类的名字和年龄等属性,为了应对这种问题,接口的概念就出现了。


       接口就是为了应对这种父类不能完全将子类中的共同特性抽取出来的情况。


语法如下:


关键字:interface


interface Test(接口名){


       void  function();  // 接口内的方法,省略abstract关键字。


}

使用implements 来让类实现该接口



在接口中,方法必须被定义为public或abstract的形式其他修饰限定符不被java编译器认可,即使该方法没有被public修饰,也是默认public权限,并且接口中被定义的任何字段都是自动被static和final修饰的。


实现某个接口的类,这个类就必须实现重写这个接口中的方法。

案例如下:

interface Fly{
    void fly();
}
interface Run{
    void run();
}
class Dog implements Run{
    @Override
    public void run() {
        System.out.println("dog is running");
    }
}
class Bird implements Fly{
    public void fly(){
        System.out.println( "bird is flying");
    }
}
public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Bird bird = new Bird();
        dog.run();
        bird.fly();
    }
}


       结果如图

接口类型也可是实现向上转型

 

interface Run{
    void run();
}
class Dog implements Run{
    @Override
    public void run() {
        System.out.println("dog is running");
    }
}
public class Main {
    public static void main(String[] args) {
        Run run = new Dog();
        run.run();
    }
}


结果如下:

五、final关键字

重写和继承的功能很强大,但是必然也存在着不允许被重写或者继承的情况,这个时候就可以使用final修饰类或者方法,来防止某些不允许被重写和继承的情况。


1、final防止重写

       为了方法方法被重写,需要在方法声明的开始处将final指定为修饰符,被final修饰的方法不能被重修。

class A{
    final void method(){
        System.out.println("hello");
    }
}
class B extends A{
    void method(){
        System.out.println("hello java");
    }
}


报错如下:

2、使用final放置继承

在声明类的时候可以在开始的位置加上final关键字,以防止其被其他类继承:

final class A{
    // 方法体
}
class B extends A{
    // 方法体
}


执行后显示

85cf1c028f0e372308f360e7e6daa885_b8b699899e9748118352cf29ddfd3450.png

       如果一个类被abstract和final同时修饰,是非法的。如果这个类被abstract修饰,那么其中必定包含abstract方法,abstract方法必须被重写,但是被final修饰的类,其中的方法都是隐式的被final修饰,也就是说其中的所有方法都不能被重写,因此同时被final和abstract修饰是没有意义的,是不合法的。


3、final修饰的变量

final不仅可以修饰方法和类,还可以用来修饰成员变量,如果一个变量被final修饰,那么它的值在其生命周期内就不能改变。但是可以给他初始化。final修饰的变量初始化可以直接赋值,也可以使用代码块和构造方法来对其进行初始化,不管怎么样,必须对其选取这几种方法中的一个来初始化

初始化:

1、可以使用代码块

class A{
    final int a;
    {
        a = 10;
    }
}

如果这个变量同时被static修饰,那么可以使用static静态代码块来对其进行初始化:

1. class A{
2. final static int a;
3. static {
4.         a = 10;
5.     }
6. }

2、构造器初始化

class A{
    final  int a;
    public A(int a) {
        this.a = a;
    }
}


目录
相关文章
|
22小时前
|
Java API 索引
java中String类常用API
java中String类常用API
|
21小时前
|
Java API 索引
java中ArrayList类常用API
java中ArrayList类常用API
|
23小时前
|
Java
杭电acm1201 18岁生日 Java解法 时间类
杭电acm1201 18岁生日 Java解法 时间类
5 0
|
1月前
|
Java
Java中的继承和多态是什么?请举例说明。
Java中,继承让子类继承父类属性和方法,如`class Child extends Parent`,子类可重写父类方法。多态允许父类引用指向子类对象,如`Animal a = new Dog()`,调用`a.makeSound()`会根据实际对象类型动态绑定相应实现,增强了代码灵活性和可扩展性。
19 0
|
1月前
|
搜索推荐 Java
Java的面向对象特性主要包括封装、继承和多态
【4月更文挑战第5天】Java的面向对象特性主要包括封装、继承和多态
26 3
|
1月前
|
Java 程序员 编译器
Java继承与多态知识点详解
本文主要讲解的是Java中继承与多态的知识点
|
3天前
|
Java 数据安全/隐私保护
Java基础之类封装、继承、多态
Java基础之类封装、继承、多态
8 2
|
4天前
|
Java 数据安全/隐私保护 开发者
Java是一种完全支持面向对象编程的语言,其面向对象特性包括封装、继承、多态和抽象等
【6月更文挑战第18天】**面向对象编程(OOP)通过对象封装状态和行为,实现问题域的抽象。Java全面支持OOP,核心特性包括**: - **封装**:保护数据安全,隐藏内部细节。 - **继承**:子类继承父类属性和行为,促进代码重用。 - **多态**:一个接口多种实现,增强灵活性和扩展性。 - **抽象**:通过接口和抽象类抽离共性,简化复杂性。 **Java的OOP便于理解和解决复杂系统问题。**
17 3
|
3天前
|
安全 Java 数据安全/隐私保护
Java基础之类封装、继承、多态
Java基础的封装、继承和多态是OOP的核心。封装通过访问控制(如private)隐藏类的内部细节,提供公共接口供外部交互。例如,`Person`类封装`name`和`age`,通过`getName()`和`setAge()`方法访问。继承允许子类(如`Dog`)继承父类(如`Animal`)的属性和方法,并可扩展或覆盖。多态使得父类引用可指向子类对象,调用方法时根据实际对象类型执行,如不同动物的`makeSound()`。接口实现多态提供了一种定义行为而不必关心实现的方式。向上转型(子类→父类)安全且默认,而向下转型(父类→子类)需类型检查以避免异常。
6 1
|
4天前
|
安全 Java 开发者
类与对象:Java中的封装、继承与多态
Java面向对象三大特性:封装(隐藏对象细节,增强安全与复用),继承(代码复用与扩展,如Dog继承Animal),多态(统一接口,不同实现,如Playable接口的Piano和Guitar)。通过示例展示了如何在实践中应用这些概念。【6月更文挑战第16天】
13 2