java面向对象之继承(代码片段)

来日可追 来日可追     2022-10-20     780

关键词:

继承(Java面向对象三大特征之一)

  • 多个类存在相同属性和行为时,将这此内容抽取单独的一个类中,(类当中抽象出一个类(父类))

  • 减少代码量;方便修改代码

  • 父类(基类)与子类是is-a关系,子类可以直接访问父类非私有的属性和行为

1.1、使用继承

1.1.1 编写父类A

访问修饰符 class A
    // 公有属性和方法

1.1.2 编写子类B,继承父类A

访问修饰符 class B extends A
    // 子类特有的属性和方法

  • 初始化子类构造方法时,必须先执行父类的构造方法(默认先无参),子类构造方法中默认有一个super(),表示调用的父类的构造方法,先把父类初始化,再把子类初始化。(先有爸爸)

注意

  • Java中只支持单根继承,即一个类只能有一个直接父类;

*上图截自菜鸟教程

访问父类的父类的成员,使用一个super. 就可以

1.2 继承的特性

  • 子类拥有父类非 private 的属性、方法。
  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
  • 子类可以用自己的方式实现父类的方法。
  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

1.3 子类继承父类的什么?

  • 继承public和protected 修饰的属性和方法,不管子类和父类是否在同一包里;

  • 继承默认权限修饰符的属性和方法,但子类和父类必须在同一包里;

    不能被继承的父类成员:

    • private 成员;
    • 子类与父类不在同一包下,使用默认访问权限的成员;
    • 构造方法(只能调用,不能继承)

1.4 super和this关键字

super:父类对象

this:当前对象

如果子类父类中出现了 重名成员变量,这是访问是有影响的!!!

区分同名成员变量,到底是父成员变量还是子成员变量,需要使用super关键字,修饰父类的成员变量,类似于这前所学this;或者可以理解为super可以使被屏蔽掉(子父类成员变量重名了)的成员可见。

使用格式:

super.父类成员变量名

// super();super(name,health,……)——访问父类构造方法

this.子类成员变量名

note:

super调用父类构造方法时只可有一条且必须放在第一句;

super只能出现在子类的普通方法和构造方法里;

1.5 继承条件下构造方法的调用原则

  • 不管是用的无参构造方法的还是有参的去构造子类对象,只要子类的相应构造方法 没有通过super显示调用,系统都默认先走父类无参构造,再走相应子类的无参或带参构造;

  • 如果子类的相应构造方法里出现 通过super显示调用父类有参构造方法,则执行父类相应有参构造方法,而不执行父类无参构造方法。

note:

调用 自己本类的构造方法:

public PP() // 无参构造
public PP(String name,int age)
    // 方法体

public PP(String name,int age,String sex)
    this(name,age); // this写于首行
    // …………

二、访问权限控制

1、的访问控制;

2、类成员的访问控制;

常用的访问控制修饰符

  • public、protected、默认、private

    (修饰符用来定义类、方法或者变量,通常放在语句的最前端)

2.1 实现类的访问控制

类的访问修饰符:

  • public修饰符:

    公有访问级别,对所有类可见(包括不同包下,导入包即可用)。

    使用对象:类、接口、变量、方法

  • 默认修饰符(default,就是什么也不写):

    包级私有访问级别,在同一包内可见,不使用任何修饰符

    使用对象:类、接口、变量、方法

2.2 类成员的访问修饰符

  • private修饰符:

​ 只有本类可访问。

​ 对象:变量、方法。 注意:不能修饰类(外部类)

  • 默认修饰符:(本类、同包)

  • protected修饰符:

​ 对同一包内的类和所有子类可见。(本类、同包、子类)

​ 使用对象:变量、方法。 注意:不能修饰类(外部类)

  • public修饰符:(任何地方)

三、static 修饰符(静态)

  • 成员变量

    • 静态变量,可直接通过类名访问
  • 成员方法

    • 静态方法,可直接通过类名访问
  • 代码块

    • 静态代码块,当Java虚拟机加载类时,就会执行该代码块

3.1、类的成员变量

3.1.1 类变量(静态变量)

  • 被static修饰的变量;注意:局部变量不能被声明为 static 变量。
  • 在内存中只有一个拷贝空间;
  • 类的内部,可以在任何方法内直接访问静态变量;
  • 其它类中可以通过类名直接调用;(创建实例对象后使用也是可以的)
public class Student
    // 实例变量
    int age;
    String name;
    //类变量
    public static String email;


public class Test
    public static void main(String[] args)
       // 使用
		System.out.println(Student.email);// 类名.属性
        

3.1.2 实例变量

  • 没有被static修饰的变量;
  • 必须通过实例(对象)调用;
  • 每创建一个实例都会分配一次内存,可在内存空间有多个拷贝,且互不影响;
public class Student
    // 实例变量
    int age;
    String name;


public class Test
    public static void main(String[] args)
        Student stu=new Student();// 创建实例对象
        System.out.println(stu.age);// 使用
        

3.1.3 static变量的作用

  1. 能被类的所有实例共享,可作为实例之间进行交流的共享数据;
  2. 如果类的所有实例都包含一个相同的常量属性,可把该属性定义为静态常量类型,从而节省内存空间。
// 模拟实现选民投票过程:
// 一群选民进行一次投票,当总票数达到100时停止投票
   // 选民类
public class Voter 
    private static int count;// 投票总数
    private static final int MAX_COUNT=100;// 静态常量
    private static String name;
// 构造方法
    public Voter()
    public Voter(String name)
        this.name=name;
    
// 还可封装
   public void setName(String name)
        this.name=name;
    
    public String getName()
        return this.name;
    

    public void voteFor()
        if (count==MAX_COUNT)
            System.out.println("已停止投票!");
            return; // 结束程序
        else 
            count++;
            System.out.println(this.name+"投票成功!");
        
    


// 测试类
public class TestVoter 
    public static void main(String[] args) 
        Voter zhang=new Voter("张三");// 1号选民(构造方法的使用)
        zhang.voteFor();

        for (int i = 1; i <=99; i++) 
            Voter  names=new Voter("name"+i);
            names.voteFor();
        
    

3.2、static 方法

3.2.1 静态方法

  1. 可直接通过类名访问,(静态方法访问不不能直接访问实例的变量和方法)

  2. 静态方法中不能使用 this 和 super 为什么呢??

    静态方法不需要创建对象,而this和super与对象有关;

  3. 可直接访问静态变量和静态方法

  4. 静态方法必须被实现(得有方法体)

    为什么main方法(程序入口)是静态 ???

    在加载类的时候就会执行静态方法相关代码,而静态方法与类相关,只要加载类,就会执行与类相关的main方法,不用创建类对象就可以执行。

3.2.2 实例方法(普通方法)

  1. 实例方法可直接访问所属类的静态变量、静态方法、实例变量、实例方法
// 打印投票结果
// 静态方法
    public static void printRes()
        System.out.println("投票总数:"+count);
    

// 在测试类里调用
Voter.printRes();// 通过类名调直接用静态方法

3.3、静态代码块

JVM加载类时,加载静态代码块。

  • 如果有多个静态代码块,按顺序加载依次执行;

  • 每个静态代码块只会被执行一次

    public class StaticTest
        static int num=100;// 静态变量
        static    // 两静态代码块依次执行
            num+=100;
            System.out.println(num);// 200
        
         static
            num+=100;
            System.out.println(num);// 300
        
    
    
    StaticTest st1=new StaticTest();
    StaticTest st2=new StaticTest();
     System.out.println(StaticTest.num);// 300
    
    // 打印结果为200 200 300
    

3.4、注意

  • 方法里不能定义static 变量但可以在方法里访问静态变量,static 变量只能在类里定义;

在继承只是继承共性而个性没法很好的实现,怎么办呢:

可以先继承共性,再补全个性,于是我们有了方法重写:

四、方法重写(override)

  • 如果子类父类出现 重名的成员方法,这是访问一种特殊情况,叫做方法重写(Override)

方法重写时,可以扩展对父类所定义同名方法,是实现多态的基础

方法重写:父子(返回值类型 方法名 (方法的参数列表))必须都相同

方法重写里可以调用父类的方法;

note:

先得有继承才能有重写(必须是父子类)!!!

  1. 方法名相同;
  2. 参数列表相同;
  3. 返回值可以不一样;(返回值类型相同或是其子类)
  4. 访问权限不严于父类;(要么一样要么比你更宽松,public重写时不能是private)

父类的(非)静态方法不能被子类重写为(静态)非静态;

父类的 私有方法 不能被子类重写;( 此时本就不能继承,更不能重写)

不能抛出比父类更多的异常;

看到这里,我们就更加容易理解到:在子类重写父类方法后,这里我们可以理解为父类的方法被屏蔽(覆盖)了,此时通过super. 就可以被屏蔽的成员变量可见。

// 下面这种写法不常见,这里就是第3、的体现

// 父类方法
public Person m1()
        System.out.println("我是父类的m1方法");
        return new Person();
     

// 子类方法
public Student m1()
    // 这里Student是Person的一个子类,所以这也是方法重写
        System.out.println("我是子类的m1方法");
        return new Student();
    

4.2 方法重载(overload)和方法重写(override)区别

  • 类: 方法重载一个类有多个同名方法 ;

    父子关系中子类重写父类的方法

  • 方法返回值 :方法重载可以修改;

    方法重写方法返回值类型必须父类相一致

  • 参数列表:方法重载可以修改;

    方法重写方法参数列表不能修改

1、重载:同一个类里的多个方法,且它们同名不同参;(与访问权限修饰符、返回值无关)

2、重写:子类里重写父类方法,父子类(两个类),子父类同名同参(注意访问权限和返回值)

4.5、关于super的理解例子

// 找到程序入口然后“顺藤摸瓜”

// 父类
public class Father 
    String name="Father";
    public void m1()
        System.out.println("我是Father类的m1方法");
    

// 子类
public class Son extends Father
    String name="Son";

    /*
    方法重写了!!!
    此时原来父类的m1方法已经被Son类覆盖;
    所以在main方法中执行的是本类的方法,
    */
    public void m1()
        System.out.println("我是Son类的m1方法");
    
    public void varTest()
        super.m1(); // 此时这里才是父类的m1方法
        System.out.println(name);// 此时的name="Son"
        System.out.println(super.name);// 这里name="Father"
        super.m1();// 这时调用的是本类的方法
    
// 程序入口
    public static void main(String[] args) 
        /* super. 不能出现在静态方法区中 */
        Son son=new Son();// 找到Son类
        son.varTest();// 方法调用
        son.m1();// 执行本类的m1方法
    

/*我是Father类的m1方法
Son
Father
我是Father类的m1方法
我是Son类的m1方法
*/

java面向对象之继承(代码片段)

Java三大特性之继承本篇内容1.继承的含义2.继承的运用3.顶级父类:Object4.小结1.继承的含义          继承是Java三大特性之一。何为继承?其实继承在我们现实生活中类似于父与子,在一个家庭中,有继承家... 查看详情

java面向对象三大特征之继承和多态(代码片段)

...转型多态代码案例总结前言  上一篇博客我们介绍了Java面向对象思想以及三大特征之一的封装。本文将介绍面向对象三大特征的剩下两个特征——继承和多态,我个人认为继承和多态是三个特征中比较重要且理解起来稍有... 查看详情

面向对象之继承(代码片段)

一、继承1、什么是继承?  继承是一种新建类的方式,在python中支持一个儿子继承多个爹  新建的类称为子类或派生类  父类又可以称为基类或超类  子类会‘’遗传‘’父类的属性2、为什么要继承?  ... 查看详情

面向对象三大特性之——继承(代码片段)

面向对象三大特性之——继承继承--需要解决代码的重复继承语法:classA:passclassB(A):passB继承A,A是父类,B是子类A是父类(基类超类)B是子类(派生类)子类可以使用父类中的:方法静态变量classAnimal:def__init__(self,name):self.name=namedefea... 查看详情

面向对象之继承(代码片段)

初识继承什么是继承继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称为基类或超类,新建的类称为派生类或子类。子类会“”遗传”父类的属性,从而解决代码重用问题(比如练... 查看详情

面向对象之继承(代码片段)

标签(空格分隔):继承什么是继承:继承是指类与类之间的关系,是一种什么“是”什么的关系,继承的功能之一就是用来解决代买重用问题,继承是一种创建新类的方式,在python中,新建的类是可以继承多个父类,父类又可... 查看详情

面向对象之继承与派生(代码片段)

一、初识继承什么是继承继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称为基类或超类,新建的类称为派生类或子类。子类会“”遗传”父类的属性,从而解决代码重用问题(比... 查看详情

面向对象的三大特性之继承(代码片段)

#面向对象的三大特性之继承#当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好(如机器人)#当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好(动物——猫)#继承同时有... 查看详情

java面向对象编程之继承

前言Java语言有三大重要的特性,分别是继承、多态和封装。今天我们就来聊聊继承,继承是复用程序代码的有力手段,使用继承我们会少写许多代码,也可以让我们在写代码的时候逻辑变得更加清楚。继承的基本语法在Java语言... 查看详情

面向对象之原型继承(代码片段)

搞清楚constructor构造器、prototype构造原型、实例对象三者关系constructor就是构造函数的名字,prototype是原型对象,每个构造函数都必须有一个原型对象;构造函数要被继承的方法在这里存放才不会浪费堆区空间;构造函数里面的th... 查看详情

java中面向对象三大特性之——多态(代码片段)

多态的概述: 多态是继封装、继承之后,面向对象的第三大特性。生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也是不一样的。可见,同一行为,通过不同的... 查看详情

面向对象之继承与派生(代码片段)

一、继承  1、含义:继承指的是类与类之间的关系,是一种什么“是”什么的关系,继承的功能之一就是用来解决代码重用问题。  2、特点:继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,而... 查看详情

5_面向对象-中之面向对象的特征二:继承性(代码片段)

1.为什么要有类的继承性?(继承性的好处)  *①减少了代码的冗余,提高了代码的复用性  *②便于功能的扩展  *③为之后多态性的使用,提供了前提2.继承性的格式:  classAextendsB*A:子类、派生类、subclass*B:父类、超类... 查看详情

java面试题javase基础之java面向对象(代码片段)

JavaSE基础1、Java面向对象1.1、什么是面向对象?1.2、对象的概念1.3、面向对象和面向过程的关系和区别1.4、面向对象三大核心特性1.4.1、继承1.4.2、封装1.4.3、多态1.5、访问权限修饰符的区别1、Java面向对象1.1、什么是面向对象... 查看详情

面向对象之继承与派生(代码片段)

继承:单继承/多继承python2与python3在继承上的区别:  新式类:但凡继承object类的子类,以及该子类的子子类,...都称之为新式类  经典类:没有继承object类的子类,以及该子类的子子类,...都称之为经典类只有在python2中才区分新式类... 查看详情

面向对象三大特征之二:继承(代码片段)

Q:为什么使用继承?    为了提取两个类中公共的代码,可以使用继承抽取重复性的代码到一个公共类中,这个公共的类称为父类(superclass)。继承于父类的类称为子类(subclass)一,java继承的特性[1]单根性。在java中... 查看详情

golang如何体现面向对象三大特性之继承?(代码片段)

继承引出继承的必要性继承的基本介绍基本介绍示意图快速入门案例继承的好处继承的注意事项多重继承引出继承的必要性看一个问题,学生考试系统的程序,提出代码复用的问题。看下例代码:packagemainimport( "fmt... 查看详情

面向对象三大特征之多态(代码片段)

面向对象的三大特征:封装、继承、多态。今天重点来看一下“多态”。封装  指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。将属性或方法进行封装,防止外部程序随机访问,加强代码的安全性。继承&n... 查看详情