Java中的继承、抽象、接口、多态

本文详细介绍了Java中的面向对象特性,包括继承的概念、特点、格式,以及子类与父类的关系。接着讨论了抽象类和接口的区别,抽象类的注意事项,以及接口的定义和特点。最后,深入探讨了多态的定义、作用、好处以及在Java中的实现方式。通过实例展示了多态的运用,强调了多态在提高代码复用性和灵活性方面的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.继承


1.1概述


由来

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。如图所示:

生活中的继承

其中,多个类可以称为子类,单独那一个类称为父类、超类(superclass)或者基类。

定义

  • 继承:就是子类继承父类的属性和行为,使得子类对象具有父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。

好处

  1. 提高代码的复用性。
  2. 类与类之间产生了关系,是多态的前提。

私有属性是否可被继承
这个问题目前没有唯一的标准答案,网络上可以看到2种答案,分别是可继承和不可继承。

可以被继承,但是由于private的限制,所以在子类中不能直接访问。
不可以被继承。当构建子类对象时,首先创建父类对象,然后再创建子类对象,子类对象中包裹父类对象
子类除了拥有父类的属性和方法(拥有父类的所有成员,但是注意构造器和析构器不是成员),也可以创建自己的特性。

super:

super:当前的父类

this:代表当前的对象

注意:只能在自己本类使用

方法的覆盖(重写)Override

继承的关系中  方法名一样  参数一样  返回值类型一样(三同原则)。

object

object类是所有类的父类  创建的类都继承object类。

1.2继承的特点:

  • Java中不支持多重继承,Java中要求任何的子类只能有一个直系的双亲类。

  • 子类可以重写父类的方法。

  • 可以在子类中进行覆盖定义父类中的成员方法和成员属性。

  • Java支持多层继承(继承体系):C继承B,B继承A,就会出现继承体系。Java中的所有类都直接或者间接的集成于java.lang.Object.

  • 提高了类之间的耦合性。

1.3继承的格式

通过extends关键字,可以声明一个子类继承另外一个父类,定义格式如下:

class 父类{
    ...
}
class 子类 extends 父类{
    ...
}

下面通过代码创建父类,子类继承父类,测试代码...

package extend;
 
public class fu {
    public void show(){
        System.out.println("我是父类show 方法");
    }
    //未提供构造方法,默认有一个无参构造方法
}

子类:

package extend;
 
public class zi extends fu{
    public void show1(){
        System.out.println("子类show 方法");
    }
}

测试代码:

package extend;
 
public class test {
    public static void main(String[] args){
        //如果要调用fu类中的方法,就得创建父类对象
        //这里用无参构造方法创建对象
        fu f=new fu();
        f.show();
 
        //同理调用子类中的方法
        zi z=new zi();
        z.show1();
 
        //子调用父类中的show方法
        zi z_extend=new zi();
        z_extend.show();
    }
}

2.抽象


2.1抽象类

父类:public abstract class  自定义的类名(){}

子类:public class 子类名称 extends  自定义的类名(){}

定义格式

public interface 接口名称{

            //抽象方法

            //默认方法

            //静态方法

            //私有方法

}

含有抽象方法

抽象方法:使用 abstract 关键字修饰,可以省略,没有方法体。该方法供子类实现使用。
代码如下:

public interface InterFaceName{
public abstract void method()

}

含有默认方法和静态方法

默认方法:使用 default修饰,不可省略,供子类调用或者子类重写。
静态方法:使用static修饰,供接口直接调用。
代码如下:

public interface InterFaceName {
public default void method(){
// 执行语句
public static woid method2(){
// 执行语句
)

}

}

含有私有方法和私有静态方法

私有方法:使用private 修饰,供接口中的默认方法或者静态方法调用。

代码如下:

public interface InterFaceName{
private void method1(){
// 执行语句
}
private static void method2(){
// 执行语句
}
}

2.2抽象类的注意事项:


  1. 如果一个类中含有抽象方法,那这个类肯定是抽象类(且类和方法都必须用abstract修饰方法没有方法体)
  2. 抽象类中是可以不定义抽象方法
  3. 抽象类不能直接创建对象,必须通过子类实现
  4. 子类必须重写父类抽象方法
  5. abstract 不能与static、final斌并列修饰同一个方法(因为final修饰的方法是不能被重写的,但是abstract 修饰的方法必须要重写,冲突)

3.接口


接口

定义所有的方法都是抽象的。

父类:public interface  自定义的接口名(){}

子类:public class  子类名称  implements  自定义的接口接口名(){}

属性

固定的修饰符修饰  public static final 相当于常量

方法

固定的修饰符修饰  public abstract ,无方法体

特点

  1. 不可以创建对象(因为是特殊的抽象类,因为抽象的方法没有任何意义)
  2. 子类需要重写接口中所有的抽象方法,子类就可以实例化
  3. 类可以实现接口(解决了继承的弊端)(可以new对象)

抽象类与接口的区别

  1. 抽象类中有构造方法,接口中无构造方法。
  2. 接口和接口之间支持多继承,类和类之间只能单继承。
  3. 一个类可以实现多个接口,但只能继承一个抽象类。

Java中可以使用访问修饰符来保护对类、变量、方法和构造方法的访问。

  • default:(即默认,什么也不写):在同一包内可见。 使用对象:类、接口、变量、方法。

  • private:在同一类内可见。 使用对象:变量、方法。注意:不能修饰类(外部类)

  • public:对所有类可见。 使用对象:类、接口、变量、方法。

  • protected:对同一包内的类和所有子类可见。使用对象:变量、方法。注意:不能修饰类(外部类)

  1. public: 共有修饰符,所有类都可以访问,可以修饰类、数据成员、构造方法及方法成员
  2. private: 私有修饰符,只有在当前类中可以调用,可以修馆布数据成员、构造方法及方法成员,不可以修饰类
  3. protected: 保护修饰符,只有子类可以调用,可以修饰数据据成员、构造方法和方法成员,不可以修饰类
  4. default:(默认修饰符):只能被当前类或同包下被调用,类、方法、成员都可以使用默认权限,即不被private、 protected,public修饰

Java中,请说明final关键字的使用

final 表示最终的,可以修饰类、方法、变量
final 修饰类,表示此类为最终类,不能被继承
final 修饰方法,表示此方法为最终方法,不能被重写

final 修饰变量,表示此变量为最终变量及常量

4.多态


4.1概述


引入

多态是继封装、继承之后,面向对象的第三大特性。

生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也是不一样的。可见,同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。

定义

多态: 是指同一行为,具有多个不同表现形式

前提(重点)

  1. 继承或者实现【二选一】
  2. 方法的重写【意义体现: 不重写,无意义】
  3. 父类引用指向子类对象【格式体现】

4.2多态的体现


多态体现的格式:

父类类型 变量名  new 子类对象;
变量名.方法名();

父类类型: 指子类对象继承的父类类型,或者实现的父接口类型。

代码如下:

Fu f = new Zi();
f.method();

那么为什么要用多态呢?具有两个好处:

1.应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。//继承
2.派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。 //多态的真正作用.

代码如下:

定义父类:

​
public abstract class Animal {
    public abstract void eat();
}

​

定义子类:

class Cat extends Animal {
  public void eat() {
       System.out.println("吃鱼");
  }
}

class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
  }
}

多态的特点:

对象类型和引用类型之间具有继承(类)/实现(接口)的关系;
引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定;
多态不能调用“只在子类存在但在父类不存在”的方法;
如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法。

下面伪代码举例多态:

父类方法:a
子类方法:a,b
父类 A = new 子类();//多态
A.a();//执行的是子类方法
A.b();//会报错,因为父类没有方法b
(子类)A.b();//支持,把A强制转换为子类

4.3多态详解


面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。

多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)

实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

多态的作用:消除类型之间的耦合关系。

现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

4.4多态的好处:


1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。


2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。


3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。


4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。


5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。


经典实例:

public class A {  
    public String show(D obj) {  
        return ("A and D");  
    }  
  
    public String show(A obj) {  
        return ("A and A");  
    }   
  
}  
  
public class B extends A{  
    public String show(B obj){  
        return ("B and B");  
    }  
      
    public String show(A obj){  
        return ("B and A");  
    }   
}  
  
public class C extends B{  
  
}  
  
public class D extends B{  
  
}  
  
public class Test {  
    public static void main(String[] args) {  
        A a1 = new A();  
        A a2 = new B();  
        B b = new B();  
        C c = new C();  
        D d = new D();  
          
        System.out.println("1--" + a1.show(b));  
        System.out.println("2--" + a1.show(c));  
        System.out.println("3--" + a1.show(d));  
        System.out.println("4--" + a2.show(b));  
        System.out.println("5--" + a2.show(c));  
        System.out.println("6--" + a2.show(d));  
        System.out.println("7--" + b.show(b));  
        System.out.println("8--" + b.show(c));  
        System.out.println("9--" + b.show(d));        
    }  
}  

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值