ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

大数据Java基础DAY9(面向对象——继承)

2022-01-18 20:31:46  阅读:195  来源: 互联网

标签:Java DAY9 子类 System 面向对象 println 父类 public out


目录

代码块

a.局部代码块:  

b.构造代码块:

c.静态代码块

继承

继承概述

继承案列

继承的好处

Java中继承的特点

Java中继承的注意事项

继承中成员变量的关系

super关键字

继承中构造方法的关系

继承中成员方法的关系

方法重写概述

final关键字


代码块

在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(到多线程再说)。

a.局部代码块:  

         在方法中出现;限定变量生命周期,及早释放,提高内存利用率。

        在同一个类的同一个方法中,如果存在多个局部代码块,执行顺序是自上而下的

   

public class Test1 {
    public static void main(String[] args) {
           //第一个代码块
        {
            int a=100;
            System.out.println(a);
        }
            //第二个代码块
        {
            int b =200;
            System.out.println(b);
        }
            //第三个代码块
        {
            int c=300;
            System.out.println(c);
        }
    }
}

b.构造代码块:

在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行。

class Demo{
    //创建一个无参构造方法
    Demo(){
        int a=10;
        System.out.println(a);
    }
    //创建一个构造代码块(定义在类中方法外,用大括号括起来的代码,称为构造代码块)
    {
        int b=20;
        System.out.println(b);
    }
}
public class Test2 {
    public static void main(String[] args) {
        //创建Demo的对象
        Demo demo = new Demo();
        //创建一个局部代码块
        {
            int c=30;
            System.out.println(c);
        }
    }
}

 可以看出当一个类中既存在构造方法又存在构造代码块,在创建对象时,会先执行构造代码块,再执行构造方法,而main方法里还是自上而下执行。

c.静态代码块

在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且值执行一次。

class Demo{
    //创建一个无参构造方法
    Demo(){
        int a=10;
        System.out.println(a);
    }
    //创建一个构造代码块(定义在类中方法外,用大括号括起来的代码,称为构造代码块)
    {
        int b=20;
        System.out.println(b);
    }
    //创建一个静态代码块
    static {
        int d=40;
        System.out.println(d);
    }
}
public class Test2 {
    public static void main(String[] args) {
        //创建Demo的对象
        Demo demo = new Demo();
        //创建一个局部代码块
        {
            int c=30;
            System.out.println(c);
        }
    }
}

 静态代码块优先其他代码块执行,不创建对象也会执行。

最后我们整合一下:

class Demo3{
    Demo3(){
        System.out.println("Demo3的无参构造方法");
    }

    static {
        System.out.println("Demo3中的静态代码块");
    }

    {
        System.out.println("Demo3中的构造代码块");
    }
}
public class Test3 {
    static {
        System.out.println("Test3中的静态代码块");
    }

    public static void main(String[] args) {
        {
            System.out.println("main方法中的局部代码块");
        }

        Demo3 demo3 = new Demo3();  //创建Demo3的对象
    }
}

Demo3类需要创建对象才能访问,所以先走Test3类,Test3中静态代码块优先,再执行main方法里面的。直到创建了Demo3的对象,开始按静态代码块——构造代码块——构造方法的顺序执行。

继承

继承概述

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

b.通过extends关键字可以实现类与类的继承

      格式: class 子类名 extends 父类名 {}  

c.单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类。 有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员。

继承案列

class Father{
    //创建父类,定义成员变量
    String name;
    int age;

    public void sleep(){  //定义一个方法
        System.out.println("睡觉");
    }
}

class Son{
    //创建一个子类,定义成员变量
    String name;
    int age;
    
    public void sleep(){
        System.out.println("睡觉");
    }
}

当我们创建了两个或更多有共同之处的类的时候,发现这样就很麻烦,如上父与子类都有相同的成员变量,都有一个共同的方法,所以我们能利用继承来改进。

改进后:

class Person{  //定义一个人类,提取出父与子的相同处
    String name;
    int age;

    public void sleep(){
        System.out.println("睡觉");
    }
}

class Father extends Person{  //创建父类继承人类
}

class Son extends Father{ //创建子类继承父类

    public void play(){  //创建一个子类特有的方法
        System.out.println("玩游戏");
    }
}

public class Extends1 {
    public static void main(String[] args) {
        //创建父类对象
        Father father = new Father();
        father.sleep();   //父类通过继承能访问Person类的方法

        //创建子类对象
        Son son = new Son();
        son.sleep();   //子类通过继承能访问Person类的方法
        son.play();    //子类也可以访问自身特有的方法
    }
}

 使用继承后,父与子类都能访问Person类的方法,而且子类也能访问自己特有的方法。

继承的好处

a.提高了代码的复用性

                        多个类相同的成员可以放到同一个类中

b.提高了代码的维护性

                        如果功能的代码需要修改,修改一处即可

c.让类与类之间产生了关系,是多态的前提

                         其实这也是继承的一个弊端:类的耦合性很强

Java中继承的特点

a.Java只支持单继承,不支持多继承。

          一个类只能有一个父类,不可以有多个父类。

           class SubDemo extends Demo{}    (正确)

           class SubDemo extends Demo1,Demo2...  (错误)

b.Java支持多层继承(继承体系)

            class A{}

            class B extends A{}

            class C extends B{}

Java中继承的注意事项

a.子类只能继承父类所有非私有的成员(成员方法和成员变量)

            其实这也体现了继承的另一个弊端:打破了封装性

b.子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。

c.想要初始化子类,必须先初始化父类

d.不要为了部分功能而去继承

继承中成员变量的关系

案例:

class Father2 {  //创建父类
    int a = 40;
    int b =50;
    public void num2() {
        System.out.println(a);
    }
}
class Son2 extends Father2 { //子类继承父类

         int a = 20;
    public void num1() {
        System.out.println(a);
    }

    public void num3(){
        System.out.println(b);
    }
}
public class Extends2 {
    public static void main(String[] args) {
        //创建子类对象
        Son2 son2 = new Son2();
             son2.num1();   //就近原则,输出的应该是Son2中的a
             son2.num2();   //子类中没有该方法,到父类中寻找
             son2.num3();   //子类中没有元素b,去父类寻找
    }
}

结论

在子类方法中访问一个变量

a.首先在子类局部范围找 

b.然后在子类成员范围找

b.最后在父类成员范围找(肯定不能访问到父类局部范围)

d.如果还是没有就报错。(不考虑父亲的父亲…)

super关键字

class Father3{
    int num=30;
}
class Son3 extends Father3{

    int num =40;

    public void show(){
        int num=50;
        System.out.println(num); //可以访问到show方法里面的num
        System.out.println(this.num);  //使用在封装里说的this关键字可以访问到类中的num
    }
}
public class Extends3 {
    public static void main(String[] args) {

        Son3 son3 = new Son3();
        son3.show();
    }
}

如上,我们可以访问到子类方法里面的num,也可以利用this关键字访问子类中方法外的num,那如果我们想访问父类中的num呢,Java里提供了一个关键字:super

(在上面代码子类show方法里加入 System.out.println(super.num);就可以访问父类里面的num)

 super的用法和this区别

                             this代表本类对应的引用。

                             super代表父类存储空间的标识(可以理解为父类引用)

用法(this和super均可如下使用)

a.访问成员变量:

                     this.成员变量        

                     super.成员变量 

b.访问构造方法

                      this(…)      

                      super(…)

c.访问成员方法

                      this.成员方法()    

                      super.成员方法()

继承中构造方法的关系

子类中所有的构造方法默认都会访问父类中空参数的构造方法。

因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。 每一个构造方法的第一条语句默认都是:super()

例:

class Father4{

    Father4(){
        System.out.println("这是父类中的无参构造方法");
    }
    
    Father4(String s){
        System.out.println("这是父类中的有参构造方法"+s);
    }
}
class Son4 extends Father4{
    Son4(){
        System.out.println("这是子类中的无参构造方法");
    }
    
    Son4(String s){
        System.out.println("这是子类的有参构造方法"+s);
    }
}
public class Extends4 {
    public static void main(String[] args) {
        //创建子类对象
        Son4 son4 = new Son4("User");
    }
}

 

当父类中没有无参构造方法:

a.子类通过super去显示调用父类其他的带参的构造方法

例:

class Father4{

    Father4(String s){
        System.out.println("这是父类中的有参构造方法"+s);
    }
}
class Son4 extends Father4{
    Son4(){
        super("FU");
        System.out.println("这是子类中的无参构造方法");
    }

    Son4(String s){
        super("FU");
        System.out.println("这是子类的有参构造方法"+s);
    }
}
public class Extends4 {
    public static void main(String[] args) {
        //创建子类对象
        Son4 son4 = new Son4("User");
    }
}

b.子类通过this去调用本类的其他构造方法

          本类其他构造也必须首先访问了父类构造

例:

class Father4{
    Father4(String s){
        System.out.println("这是父类中的有参构造方法"+s);
    }
}
class Son4 extends Father4{
    Son4(){
        super("FU");
        System.out.println("这是子类中的无参构造方法");
    }
    Son4(String s){
        this();  //使用this关键字,先调用子类的无参构造方法 ,间接的调用父类构造方法
        System.out.println("这是子类的有参构造方法"+s);
    }
}
public class Extends4 {
    public static void main(String[] args) {
        //创建子类对象
        Son4 son4 = new Son4("User");
    }
}

c.一定要注意: super(…)或者this(….)必须出现在第一条语句上, 否则,就会有父类数据的多次初始化

继承中成员方法的关系

子父类中同名和不同名的成员方法

class Father5{
    public void show(){
        System.out.println("父类中的show方法");
    }

    public void show3(){
        System.out.println("父类中的show3方法");
    }
}

class Son5 extends Father5{
    public void show(){
        System.out.println("子类中的show方法");
    }
    public void show2(){
        System.out.println("子类中的show2方法");
    }
}
public class Extends5 {
    public static void main(String[] args) {
        Son5 son5 = new Son5();
        son5.show();  //调用子类的show方法,就近原则
        son5.show2();  //调用子类的show2方法
        son5.show3(); //子类访问show3方法,子类没有去父类中找
    }
}

结论: 通过子类对象去访问一个方法,首先在子类中找,然后在父类中找,如果还是没有就报错。

方法重写概述

子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写。

使用特点:

               如果方法名不同,就调用对应的方法

               如果方法名相同,最终使用的是子类自己的

方法重写的应用:

              当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。

例:

class Father6{
    public void study(String s){
        System.out.println("学习"+s);
    }
}

class Son6 extends Father6{
    public void study(String s){        //重写父类中的study方法
        System.out.println("学习"+s+"中的继承");
    }
    public  void study2(String s){
        System.out.println("学习"+s);  //子类特有的方法
    }
}
public class Extends6 {
    public static void main(String[] args) {
        //创建子类对象
        Son6 son6 = new Son6();

        son6.study("java");   //调用子类的study方法
        son6.study2("大数据");
    }
}

 方法重写的注意事项

a.父类中私有方法不能被重写

b.子类重写父类方法时,访问权限不能更低

c.父类静态方法,子类不能进行重写

方法重写与方法重载的区别

方法重写(override)是发生在继承关系中子类里的,方法重载(overload)是发生在同一个类中的

重载是方法名一样,参数列表不一样

重写是方法名,参数列表,返回值都一样,实现不一样,叫方法的重写。

final关键字

 final关键字是最终的意思,可以修饰类,成员变量,成员方法。
 

特点:

a.修饰方法,方法不能被重写

例:当我们不想让子类覆盖重写父类中的方法或者功能,只能让子类去使用时,可以使用final

class Father7{
    public final void show(){   //使用final修饰方法
        System.out.println("父类中的show方法");
    }
}

class Son7 extends Father7{
   @Override
    public  void show(){      //子类不能重写,否则报错
        System.out.println("这是子类中的show方法");
    }
}
public class Extends7 {
    public static void main(String[] args) {
        Son7 son7 = new Son7();
        son7.show();
    }
}

 可以看到子类如果重写了父类用final修饰的方法,运行就会报错。

b.修饰类,类不能被继承

c.修饰变量,变量就变成了常量,只能被赋值一次(在构造方法完毕之前赋值即可)

final修饰局部变量

      a. 在方法内部,该变量不可以被改变

      b. 在方法声明上,基本类型和引用类型作为参数的情况

                      基本类型,是值不能被改变

                      引用类型,是地址值不能被改变(该对象堆内存中的值是可以改变的)

      c.final修饰变量的初始化时机

                       在对象构造完毕前即可

面向对象三大特征——封装https://blog.csdn.net/qq_52400447/article/details/122520149

标签:Java,DAY9,子类,System,面向对象,println,父类,public,out
来源: https://blog.csdn.net/qq_52400447/article/details/122546522

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有