Java基础知识----继承!!!

本文介绍了Java中的继承概念,旨在提高代码复用性和维护性。讲解了继承的格式、优点、缺点、特点以及注意事项。强调了继承中成员变量、构造方法和成员方法的关系,并通过面试题探讨了`override`与`overload`的区别以及`this`和`super`关键字的应用场景。

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

1、继承

继承概念的引入:

/**
* 学生类
*/
public class Student{
//成员变量
  String name;
  int age;

 //get和set方法
 
 //构造方法
 public Student(){
 }
 //成员方法
 public void eat(){}
 public void sleep(){}  
}
/**
* 教师类
*/
public class Teacher{
 //成员变量
 String name;
 int age;
 //get,set方法
 //构造方法
 public Teacher(){
 }
 //成员方法
 public void eat(){}
 public void sleep(){}
}

分析: 通过代码我们发现这两个类中有许多相同的代码,如果继承定义工人类,军人类等等,重复的代码会越来越多。
*思考: *我们能否将相同的代码提取出来,定义到一个独立的类中,并让这多个类与这个独立的类产生一个关系,有了这个关系,就可以让这多个类具有这个独立类的属性和功能,为了实现这个功能,Java提供了一个技术,叫做:继承。
继承的格式: 关系需要借助一个关键字—extends

class Fu{

}
class Zi extends Fu{

}

改进案例:

class Person {//人类
  String name;
  int age;
  //get和set方法
  public void eat(){}
  public void sleep(){}
}
/**
* 学生类
*/
class Student extends Person{

public Student(){}

}
/**
* 教师类
*/
class Teacher extends Person{

public Teacher(){}

}

代码演示:

package org.wdzl.unit03;
/**
 * 继承的演示案例:
 *        继承:把多个类中相同代码提取到独立的类中。
 *        实现继承:使用extends关键字
 *        格式:子类 extends 父类{}
 *        优点:1、提高了代码的复用性
 *             2、提高了代码的维护性
 *             3、继承是多态的前提
 */
public class ExtendsDemo1 {
    public static void main(String[] args) {
        //使用继承前
        Student1 student1 = new Student1();
        student1.eat();
        student1.sleep();
        System.out.println("------------");
        Teacher1 teacher1 = new Teacher1();
        teacher1.eat();
        teacher1.sleep();
    }
}

class Person{
    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}

class Student1 extends Person{

}

class Teacher1 extends Person{

}

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

package org.wdzl.unit03;
/**
 * 继承的演示案例:
 *        继承:把多个类中相同代码提取到独立的类中。
 *        实现继承:使用extends关键字
 *        格式:子类 extends 父类{}
 *        优点:1、提高了代码的复用性
 *             2、提高了代码的维护性
 *             3、继承是多态的前提
 */
public class ExtendsDemo1 {
    public static void main(String[] args) {
        //使用继承前
        Student1 student1 = new Student1();
        student1.eat();
        student1.sleep();
        System.out.println("------------");
        Teacher1 teacher1 = new Teacher1();
        teacher1.eat();
        teacher1.sleep();
    }
}

class Person{
    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}

class Student1 extends Person{

}

class Teacher1 extends Person{

}

继承的优点:
1、提高了代码的复用性
2、方便了代码的维护
3、继承的多态的前提
继承的缺点: 1、增加了类与类之间的耦合性。违背了面向对象的初衷:“高内聚,低耦合”
内聚:就是自己完成某事的能力。
耦合:类与类之间的关系
2、打破了封装性。

package org.wdzl.unit03;
/**
 * 继承的演示案例:
 *        继承:把多个类中相同代码提取到独立的类中。
 *        实现继承:使用extends关键字
 *        格式:子类 extends 父类{}
 *        优点:1、提高了代码的复用性
 *             2、提高了代码的维护性
 *             3、继承是多态的前提
 */
public class ExtendsDemo1 {
    public static void main(String[] args) {
        //使用继承前
        Student1 student1 = new Student1();
        student1.eat();
        student1.sleep();
        System.out.println("------------");
        Teacher1 teacher1 = new Teacher1();
        teacher1.eat();
        teacher1.sleep();
    }
}

class Person{
    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}

class Student1 extends Person{

}

class Teacher1 extends Person{

}

继承的特点: 1、单继承:只能有一个父类
2、多层继承,实现继承体系。
单独的这个类称为父类,基类或者超类;这多个类叫做子类或者派生类。
有了这个继承以后,我们定义一个类的时候可以在一个已经存在的类的基础上,还可以定义自己新的成员。

package org.wdzl.unit03;

/**
 * 继承的特点:
 *   1、Java中,只支持单继承
 *   2、Java支持多层继承,可以形成一个继承体系。
 */
public class ExtendsDemo2 {
    public static void main(String[] args) {
        Son son = new Son();
        son.method2();
        son.method1();
    }
}
class Father extends GrandFather{
    public void method1(){
        System.out.println("我是你爹!!!");
    }
}
class GrandFather{
    public void method2(){
        System.out.println("我是你爷爷!!!");
    }
}
class Son extends Father{

}

继承的注意事项:
1、子类不能继承的私有方法,但是可以继承父类的私有属性
2、子类不能继承父类的构造方法,但是可以通过super关键字来访问,
3、如果类与类之间的关系符合“is a”关系,我们就可以选择使用继承,不要因为一个类的某几个功能而去继承。

package org.wdzl.unit03;

/**
 * 继承在使用时的注意事项:
 *      1、子类只能继承父类非私有的成员变量和方法。
 *      2、子类不能继承父类的构造方法,但是可以通过super(后面讲)关键字去访问。
 *      3、在选择继承时,不要因为某一部分来选择继承,我们在选择继承时,要注意一种关系:“is a”
 *           举例:
 *           class A {
 *               function();
 *               function2();
 *           }
 *           class B {
 *               function2();
 *               function3();
 *           }
 *      我们发现代码中,class B和class A都有function2(),我们就使用继承修饰class B
 *           class B extends A{
 *               function2();
 *           }
 *           这样改造存在一个问题:就是class B中无形多出可一个function()方法,然而这个方法不是我们想要的。
 *
 */
public class ExtendsDemo3 {
    public static void main(String[] args) {
        //创建对象
        Son2 son2= new Son2();
        son2.method();
        //子类不能访问父类的私有方法
//        son2.function();//爆红
    }
}
class Father2{
    //成员变量
    public int num = 2;
    private int num2 = 4;
    //构造方法
    public Father2(){
        System.out.println("无参构造");
    }
    //成员方法
    public void method(){
        System.out.println(num);
        System.out.println(num2);
    }
    private void function(){
        System.out.println(num);
        System.out.println(num2);
    }
}
class Son2 extends Father2{
    public Son2(){
        super();
    }
    public void method2(){
        System.out.println(num);
        //子类不能访问父类的私有成员变量
//        System.out.println(num2);//爆红
    }
}

继承中成员的关系:
1、成员变量:
a、变量相同:
①:在子类的局部位置查找
②:在子类的成员位置寻找
③:在父类的成员位置寻找
④:还找不到就报错
b、变量名不同

package org.wdzl.unit03;

/**
 * 父类的成员变量和子类的成员变量同名问题
 *     1、在子类的局部变量中寻找;
 *     2、在子类的成员变量中寻找;
 *     3、在父类的成员变量中寻找;
 *     4、在以上三个地方都没有找到就会报错。
 *     注意:继承不能继承父类的局部变量。
 */
public class ExtendsDemo4 {
    public static void main(String[] args) {
        Son3 son3 = new Son3();
        System.out.println(son3.function());
    }

}

class Father3{
    public int a = 10;
    public int method(){
        int a = 20;
        return a;
    }
}

class Son3 extends Father3{
    //public int a = 30;
    public int function(){
        //int a = 40;
        return a;
    }
}

2、构造方法
1、子类的所有构造方法会默认的去访问父类的无参构造。
原因:子类如果要访问父类的属性或方法,则父类也需要完成初始化。

package org.wdzl.unit03;

/**
 * 继承中的构造方法的关系
 *    1、子类中所有的构造方法都默认会访问父类中的无参构造方法
 *    原理:
 *       因为继承的关系,子类对象可以使用父类的非私有的属性和方法,所以在创建子类对象前必须对父类的数据进行初始化,也急就是创建父类的对象。
 *
 *    注意:
 *       子类的所有构造方法第一句都是super();
 */
public class ExtendsDemo6 {
    public static void main(String[] args) {
        Son5 son5 = new Son5();
        System.out.println("------------");
        Son5 son51 = new Son5("张三");
    }
}
class Father5{
    public Father5(){
        System.out.println("父类的无参构造方法");
    }
    public Father5(String name){
        System.out.println("父类的有参构造方法");
    }
}
class Son5 extends Father5{
    public Son5(){
        System.out.println("子类中的无参构造方法");
    }

    public Son5(String name){
        System.out.println("子类的有参构造");
    }
}

2、父类中没有无参构造解决办法:
a、通过super关键字指定的访问父类的有参构造方法,完成父类的初始化。
b、通过this关键字调用自身其他的构造方法,但是调用的这个构造方法必须完成对父类构造方法的访问。
c、手动的给出父类无参构造

package org.wdzl.unit03;

/**
 * 继承中构造方法的注意事项:
 *    1、如果父类中没有无参构造方法,我们将无法创建子类对象。
 *         解决办法:
 *              a、在父类中添加无参构造
 *              b、通过使用super关键字指定调用父类的有参构造方法。
 *              c、子类可以通过this去调用本类中的其他构造方法,
 *              子类一定要有一个构造方法访问了父类地构造方法,这样才能保证父类能够被初始化。
 *    2、this和super关键字都必须放在构造方法地第一句,并且不能同时使用这两个关键字。
 *
 */
public class ExtendsDemo7 {
    public static void main(String[] args) {
        //Son6 son6 = new Son6();
        Son6 son61  = new Son6("张三");
    }
}
class Father6{

//    public Father6(){
//        System.out.println("父类的无参构造");
//    }
    public Father6(String name){
        System.out.println("父类的有参构造方法");
    }
}
class Son6 extends Father6{
    public Son6(){
        super("张三丰");//显性的指定调用父类的有参构造
        System.out.println("子类的无参构造方法");
    }
    public Son6(String  name){
        this();//本类的无参构造
        System.out.println("子类的有参构造");
    }

}

3、成员方法

   a、方法名相同(方法的重写override)
        ①:先去子类寻找
        ②:在父类中寻找
        ③:找不到就报错
   b、方法名不同
package org.wdzl.unit03;

/**
 * 继承关系中成员方法地关系:
 *    1、方法名不同
 *    2、方法名相同:
 *       a、首先在子类中找
 *       b、在父类中找
 *       c、都找不到就报错
 *  方法地重写:对子类和父类中方法声明完全一致,就称为方法重写。
 *  方法重载:一个类中方法名相同,参数列表不用。
 *  方法重写的应用:可以重写父类的方法,使子类即拥有父类同名的方法,也可以拥有子类自己特有的方法。
 */
public class ExtendsDemo8 {
    public static void main(String[] args) {
        NewPhone newPhone = new NewPhone();
        newPhone.playGame("英雄联盟");
        newPhone.watchNews("新闻");
        System.out.println("----------------");
        newPhone.call("拜登");
    }
}
class Phone{
    public void call(String name){
        System.out.println("给"+name+"打电话");
    }
    public void watchNews(String news){
        System.out.println("看新闻");
    }
}
class NewPhone extends Phone{
    public void call(String name){
        super.call("唐某人");
        System.out.println("给"+name+"打视频电话");
    }
    public void playGame(String name){
        System.out.println("玩"+name+"这个游戏");
    }
}

面试题:
1、override和overload的区别?overload是否可以改变返回值类型?
override 重写
首先实在两个类中,并且这两个类是继承关系,然后在子类中,方法的声明与父类的声明基本一样(访问修饰符可以不同,子类不能比父类小)
overload 重载
首先是在一个类中,然后,出现多个方法名相同,但是参数列表不同的情况下,这种情况叫做重载,方法重载只与参数列表有关,与返回值没有关系。

package org.wdzl.unit03;

/**
 * 方法重写注意事项:
 *   1、父类的私有方法不能被重写。
 *   2、子类重写父类的方法时,访问权限不能降低。
 *   3、父类的静态方法,子类也必须通过静态方法去重写。(它不是方法重写,但表现形式和方法重写类似)
 *     子类覆盖父类的方法时,只要保证声明完全一致,就不会出现上面的一些问题。
 */
public class ExtendsDemo9 {
    public static void main(String[] args) {
        Son7 son7 = new Son7();
        Son7.function();

    }
}
class Father7{
//    private void method(){
//        System.out.println("Father  method");
//    }
 void method(){
    System.out.println("Father  method");
}
public static void function(){
    System.out.println("Father static function");
}
}
class Son7 extends Father7{
//    private void method(){
//        System.out.println("Son method");
//    }
   public void method(){
    System.out.println("Father  method");
}
    public static void function(){
        System.out.println("Son static function");
    }
}

2、this和super关键字的区别,以及各自的应用场景?
this:代表当前类的对象的引用
super:代表对父类对象的引用
应用场景:
成员变量:
this.成员变量:当前类的成员变量
super.成员变量:父类的成员变量
成员方法:
this.成员方法:当前类的成员方法
super.成员方法:访问父类的成员方法
构造方法:

package org.wdzl.unit03;

/**
 * 如果我们想输出子类的成员变量的值,该如何操作?
 *       使用this关键字
 *  如果我们想输出父类的成员变量的值,该如何操作?
 *       可以借助super关键字
 *  this和super之间的区别:
 *     概念上的区别:
 *        1、this代表的是当前类的引用,我们实例起的对象名就是存储的地址。
 *        2、super代表的是父类的引用,
 *     使用上的区别:
 *        1、调用成员变量
 *        this.成员变量:调用的是本类的成员变量
 *        super.成员变量:调用的是父类的成员变量
 *        2、调用构造方法
 *        this.构造方法:调用本类的构造方法
 *        super.构造方法:调用父类的构造方法
 *        3、调用成员方法
 *        this.成员方法:调用本类的构造方法
 *        super.成员方法:调用父类的构造方法
 *
 */
public class ExtendsDemo5 {
    public static void main(String[] args) {
        Son4 son4 = new Son4();
        System.out.println(son4.function());
    }

}

class Father4{
    public int a = 10;
    public int method(){
        int a = 20;
        return a;
    }
}

class Son4 extends Father4{
    public int a = 30;
    public int function(){
        int a = 40;
        //return this.a;
        return super.a;
    }
}
 this.(……):当前类的构造方法
 this.(……):父类的构造方法
package org.wdzl.unit03;

/**
 * 继承中构造方法的注意事项:
 *    1、如果父类中没有无参构造方法,我们将无法创建子类对象。
 *         解决办法:
 *              a、在父类中添加无参构造
 *              b、通过使用super关键字指定调用父类的有参构造方法。
 *              c、子类可以通过this去调用本类中的其他构造方法,
 *              子类一定要有一个构造方法访问了父类地构造方法,这样才能保证父类能够被初始化。
 *    2、this和super关键字都必须放在构造方法地第一句,并且不能同时使用这两个关键字。
 *
 */
public class ExtendsDemo7 {
    public static void main(String[] args) {
        //Son6 son6 = new Son6();
        Son6 son61  = new Son6("张三");
    }
}
class Father6{

//    public Father6(){
//        System.out.println("父类的无参构造");
//    }
    public Father6(String name){
        System.out.println("父类的有参构造方法");
    }
}
class Son6 extends Father6{
    public Son6(){
        super("张三丰");//显性的指定调用父类的有参构造
        System.out.println("子类的无参构造方法");
    }
    public Son6(String  name){
        this();//本类的无参构造
        System.out.println("子类的有参构造");
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值