java基础第二篇

本文深入解析Java中的构造代码块、构造函数、静态函数、继承、final关键字、抽象类、接口及多态等核心概念,详细阐述了它们的使用场景、执行顺序及注意事项。

目录

说一下构造代码块的问题

关于构造函数与this的深刻讲解

静态函数

java的继承模式

final关键字

下面讲一下abstract类

简单来说一下权限修饰符的问题

下面来说一下值传递

接口

多态       


说一下构造代码块的问题

        如果所有对象都需要自动执行的一段代码,我们就可以放到构造函数里面,也就是说,把这个代码块放到构造函数里面。但是,有一个问题,我们每次new一个对象,都会在推上面开一个空间来放这些函数代码,有点浪费空间。

        那如果我们放到构造代码块里面呢。他放在方法区,公共区域,也就是说,new的时候,每一个对象都会指向这个区域,而不会单独开一个空间,浪费内存。

        这个的执行方式:

                {...}

        另外还有一个静态代码块:

                static{

                        。。。。。。.class文件加载到内存就执行了。他不需要对象,静态就不需要对象

                }

        然后还有一个自动执行的函数代码:

                构造函数。。。

        那么它们到底谁先调用?

静态构造代码块-》构造代码块-》构造函数

下面直接上代码具体说一下子父类构造函数,构造代码块,静态构造代码块的执行顺序

Demo4.java

package pxx;

public class Demo4 extends Demo4Father{

    public static void main(String[] args) {
        Demo4 demo4 = new Demo4();

    }

    public Demo4(){
        System.out.println("子类构造函数调用了");
    }

    {
        System.out.println("子类构造代码块调用了");
    }

    static {
        System.out.println("子类静态代码块调用了");
    }

}

class Demo4Father {

    public Demo4Father() {
        System.out.println("调用了父类的无参构造");
    }

    {
        System.out.println("父类构造代码块调用");
    }

    static {
        System.out.println("父类静态代码块调用了");
    }

}

运行结果:

首先必须知道两个大的前提:

        1.父类是优先于子类进行初始化操作 

        2.静态代码块最先执行,类一加载到内存就会执行

那么上面的代码一分析就会知道:子父类的静态代码块先调用,父类又比子类优先,所以,先打印父类的静态代码块,然后打印子类的静态代码块,然后又调用父类的构造代码块,无参,调用子类的构造代码块,构造函数。

关于构造函数与this的深刻讲解

        构造函数可以有多个,然后构造函数之间是可以彼此调用的,但是这个调用要通过this实现,必须是在第一个语句然后根据参数的不同,调用不同的构造函数。可以解决构造函数对象属性与形参同名的问题,但是没有this也不会报错,有默认参数。当然,this只能在非静态函数中使用(this的存在必须有对象)

静态函数

        这个也叫类方法,首先静态函数是不能直接,注意是直接,不能直接访问非静态成员与函数,因为它是先于对象存在的,由类直接参与调用。但是如果静态函数中,实例化了一个对象,那他就可以访问非静态成员与函数了啊。

        问题:如果一个函数没有直接访问非静态成员与方法,那么这个函数,就可以设置成静态函数。因为这样,我们无需对象也可以调用,常常用于工具类,比如Arrays中的toString sort方法:

        内部数据一般都是按照升序排列

        举个例子:下面是我们自己写的一个工具类,里面有一个排序方法

        

        上面的方法,然后其他类就可以去调用,通过类名就可以进行调用

        说一下主函数的意思:
                public static void main(String[] args) {
                        //说一下这个设计的好处
                }
                jvm就是一个虚拟机,固有思维,固定限制
                main:jvm虚拟机来调用的,从任何情况都可以访问,程序的主入口
                statics:jvm不知道怎么创建对象,因为要传参数,所以jvm就像一个无头苍蝇
                arguments:这个就是在执行字节文件的时候,我们可以传入参数进去,也有可能是说,程序启动需要一些参数。

                上面就是我们程序在运行的时候,就需要传入启动参数

                

                上面就是cmd中启动程序,传入了一些参数

java的继承模式

        java是单继承,也就是我们一次只能继承一个父类。我们可以通过继承间接往上面继承,继承之后默认调用父类的无参构造函数。

        不用继承,如果一个对象内部要依赖于一个对象的东西,公共的一个东西,那么实现起来就比较麻烦:

        一个对象内部的函数,可能需要去调用另外一个对象的函数,那么我们可能在一个对象内部传入一个对象,然后去调用内部的方法

        首先,子类一定会去调父类的无参构造函数。当有一个有参的构造函数时,如果没有无参存在,父类将会出现错误,前提是没有调用有参。子类想写自己的构造函数,就必须隐式调用父类无参构造函数。

        super代表父类空间的引用,包括引用成员属性与方法,super.属性名 super.方法名()。当调用父类构造方法时,必须放在第一条语句,所以,无法与this同时存在一条构造方法中(前提是在调用构造函数的时候)

        说一下,父类重写的方法:注意重写与重载不一样

        重载;根据参数个数的不同,类型的不同,来进行同名函数重载,与返回值无关

        方法重写前提:存在继承关系,子类的方法与覆盖父类的方法,这也是一种多态的体现。

        我们如何才能实现重写:

                

        下面说一下instanceof: 对象 instanceof 类别    失败直接返回错误,成功返回true

        前提:判断的对象必须与类有继承或者实现的关系

        继承一个对象,然后在new一个对象,然后用new的对象去进行判别

        如果是一个接口,然后去实现这个接口,我们在用实现接口这个类的对象去进行判别

final关键字

        最终的,它也属于一种修饰符

        1.修饰基本类型成员变量时,该变量不能重新赋值(所以第一次注意进行初始化)

        2.fianl关键字修饰一个引用类型变量时,该变量不能重新指向新的对象。

        3. final关键字修饰一个函数的时候,该函数不能被重写。

        4. final关键字修饰一个类的时候,该类不能被继承。

        5. final关键字定义的变量不能被修改。

        6.一般我们在类里面定义一个常量:public static final .....这就是一个静态成员

        7.final定义的函数不能被重写,但是可以被重载

        下面看一下,一些不能被继承的类:

        

         

         

          

        可见一些常见的数据类型相关的类都是final类型的,不能被继承,那就更不可能被重写了

下面讲一下abstract类

        讲一下需求:在你定义的的类,需要多个类去继承的时候,他们有一个共同的方法,而这个方法的具体内容不一定,我们就需要设置成抽象方法

        

  1. 抽象类里面可以有抽象方法与非抽象方法
  2. 抽象方法就是需要子类去实现的方法,抽象类不可以设置成final类,因为它就是要被继承的,他不能实例化对象。因为对象要调用方法,但是抽象类里面可能就没有方法的实体
  3. 抽象类可以有构造函数,子类就可以去调用
  4. 有抽象方法就必须定义成抽象
  5. 抽象方法不能与private共用,很明白,Privated的方法与属性不能被继承

简单来说一下权限修饰符的问题

        protected与default定义的方法,都不能在跨包之后直接进行访问。default挎包之后不能被继承,不能被访问

        protected挎包之后可以被继承下来,但是不能在外部直接进行访问

        抽象方法不能与final共用,很明白,方法不能被重写,更不要说你要去修改它,完善它了。

        抽象方法不能与static共用,因为先于对象存在,所以他可能会去调用这个方法,但是如果这个方法不存在,那么就可以造成错误。

下面来说一下值传递

        函数传递的就是变量的值

        

        上面这种情况就是把值修改成功了。分析一下changeData里面传入了一个接收了一个Data对象,但是我们分析一下这个过程,这个Data d1与这个Data d它们肯定不是同一个内存地址的变量,但是他们却是指向了堆里面相同的内存空间,所以他们可以进行数据的修改。

接口

        接口,就是拓展功能用的。接口其实就是一种抽象特殊类

        interface 接口名(所有首字母大写,按照类名处理)

        {

                1.接口中的成员变量全是常量默认修饰符public static final ,不可改,所以这个都是内部初始化好的

                2.接口中的方法全是抽象方法,让类去实现的(默认是public abstract)

                3.一个非抽象类去实现接口的时候,必须把接口中的所有抽象方法全部实现

                4.接口不能创建对象

                5.接口没有构造函数

                6.jdk1.8之后,接口内部可以有默认的default方法

        }

        接口完全就是什么都定义好了给实现它的函数用,所以不需要构造函数传值。

        接口实现方法:

                class 类名 implements 接口名

                {

                ....

                }

        接口的作用:

                1. 程序的解耦。  (低耦合)

                2. 定义约束规范。

                3. 拓展功能。

        一般我们定义接口的时候,里面默认的方法是:

                public abstract ...但是一般我们会把这两个关键字给省略掉

        回过头来说一个小问题:

                java是单继承,多实现,也就是说,我们去实现接口的时候,一次性我们可以实现很多接口,接口之间也可以继承很多接口,具体的方式如下:

        

多态
       

        一种事务的多种形态,比如函数的重载,方法的重写

        用父类变量指向子类对象:(基于父类来调用子类)

                1. 成员变量静态与非静态都是访问的父类的

                2.访问静态方法,调用的也是父类

                3.访问非静态方法,调用的是子类的方法

                4.不能访问子类特有的成员

上个代码Demo3.java

public class Demo3 {
	public static void main(String[] args) {
		//我们这里直接用多态来处理
		Father father = new Son();
		System.out.println(father.name);//这个调用是父类的成员属性,子类并没有,可以打印
		//打印子类特定的成员
		System.out.println(father.age);//子类特有成员访问不了
	}
}

class Father {

	String name = "我是父亲";
	
	public void say() {
		System.out.println("我是孩子付清");
	}	

	public void eat() {
		System.out.println("我是父亲,我可以吃饭");
	}
}

class Son extends Father {
	int age = 23;

	public void eat() {
		System.out.println("我是儿子,我也可以吃饭");
	}
}

这里很明显就会给我们报一个错误:

那如何解决访问子类特有的成员呢:

数据类型转换,把相应的数据类型转换成相应的数据成员,参考代码如下:

上面可能就是需要我们把数据类型进行转换一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值