JAVA基础总结

前置知识

开发阶段的代码在硬盘中存储,在内存中以进程的方式运行,cpu执行程序,不停的给进程分配时间片段来运行。
计算机语言将代码逻辑转换为底层的0/1使计算机识别

加载程序到JVM中的时机:

  • 执行main函数
  • 启动tomcat

创建对象

对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:

  • 声明:声明一个对象,包括对象名称和对象类型。 (1:准备一个class)
  • 实例化:使用关键字 new 来创建一个对象。(2: new 去标识出来创建对象)
  • 初始化:使用 new 创建对象时,会调用构造方法初始化对象。(3:会调用构造函数去java堆中申请空间)

变量

  • 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。 局部变量的生命周期:跟随方法执行结束而死亡
  • 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。给对象创建提供了依据模板,成员变量存储在方法区的类信息中。它在创建对象new User()的时候申请空间 , 对象死亡就消亡了
  • 类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。它存储在方法区的静态区中,而且静态成员在编译的时候就存储 进去了。

静态成员和非静态成员

静态成员是放在堆中,是共享数据。所以当线程并发时容易出现数据安全问题。非静态成员及实例变量还有成员变量,他们在被使用的时候会有入栈和出栈的过程。局部变量会会在每个线程入栈的时候创建的各自的局部变量表内。
成员变量则是在创建对象,申请堆内存的时候,在每个对象的堆空间的局部变量表中
所以,通常不被太多次改变的数据将其用static修饰为静态成员。被多次改变的,不用static

继承(复用 封装 职责分担)

== 一个类有了继承,才会有多态的概念==
super关键字就是为了给父类私有属性赋值
继承就是为了去拿一些东西,去拓展一些东西

  • super关键字就是为了给父类私有属性赋值,父类去承担一些行为逻辑。父类若没有无参构造方法,子类必须用super显示申明
  • 如果在开发中,想让子类获取父类成员属性和方法的话,尽量定义为protected.
  • 如果是私有的访问权限,那就用get公开方法获取,用super或者set公开方法赋值
  • 子类覆盖父类方法时,访问权限修饰符必须大于父类

多态

什么是多态?
Java语言是基于动态函数绑定的一种机制,要实现多态,必须先有继承。 当一个父类去调用一个子类方法的时候,并不能立即确定这个数据类型,需要在运行时自动确定其类型的过程就是多态
抽象类和接口最能体现多态

  • Java中的任何一个类都是多态的,它们能保存不止一种类型的对象。
  • 它们可以保存的是除了自身对象以外,还可以保存声明类型的子类的对象。
  • 当把子类对象赋值给父类对象的引用的时候,就会引发多态。(也称之为:向上造型)。

向上造型

  • 运行时如果不合理就会出现类型转换异常:ClassCastException
  • 拿一个子类的对象,当做父类的对象来用使用
  • 向上造型是默认的,不需要运算符

动态绑定

当一个父类存在多个子类型的时候,parent就是一种多态变量。
parent.这个动作执行时,java会自动去匹配实际的类型,这就是多态。

for(Parent parent: ParentList){
   parent.println(); // 这种多态变量,会根据自身的数据类型,自动去匹配子类的方法
}

parent.方法 这个动态称之为:函数绑定

  • 当通过对象变量调用函数的时候,调用哪个函数这个动作叫做绑定、
  • 静态绑定:根据变量的声明类型来决定(也就是说你这个变量的申明类型,我就调用这个申明类型的函数。)
  • 动态绑定:根据变量的动态类型来决定(也就是说:当实际管理的对象类型是什么,我就用那个类型的函数,因为编译器在编译的时候,根本不知道你这个具体的类型是什么?在java中选择都是动态绑定来处理函数的绑定。)
  • 在成员函数中调用其他成员函数也可以通过this这个对象变量来调用。

比如在parent.print这行的时候,其实在编译的时候并不知道具体的类型是什么。所以只能在运行的时候才能确认具体的类型。对于像java这样的程序语言来说,默认所有的绑定都是:动态绑定。

抽象类(职责分担,约束子类)

抽象类只是比普通类多了一个抽象方法,作用是约束子类

  • 含有abstract修饰符的class即为抽象类,abstract类不能创建实例对象。
  • 含有abstract方法的类必须定义为abstract classabstract class类中的方法不必是抽象的。
  • abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。

为什么会存在抽象类?

  • 因为能够让子类重写的方法,大部分情况父类是不需要去做事情,也就是必须让子类自身去实现。普通的父类是起不到约束的作用,也就是说,父类中需要覆盖的方法和普通方法这个时候就难以分辨和区分。所以就有了抽象方法abstract。接口更加将此体现的淋漓尽致。
  • 抽象类可以定义抽象方法和非抽象方法。==那么父类中的非抽象方法的意义是什么呢?==其实还是回归到继承的概念:职责分担,大部分父类的非抽象方法就是去分担子类的业务,这样便于后续的维护和升级,这样就不需要去修改每个子类。只需要修改父类的方法,当然前提是方法的访问权限必须是:public或者protected的,如果是缺省的就必须在同包package中。
  • 抽象类,在平时的业务中那些场景下可以用到抽象类呢?
  • 比如springmvc路由的继承
  • hibernate、jdbctempalte中的通用类的增删改查
  • spring框架中存在大量的抽象类,其意义就是:责任分担。

抽象类抽取公用的东西同一管理(pringmvc中路由的继承就有用到)

@RequestMapper("/api/v1")
@Controller
public abstract class BaseController(){
	//建立这样一个抽象类作为基础控制器
	//那么继承它的控制器路径最前面是"/api/v1"的就可以省略
}

建立这样一个抽象类作为基础控制器
那么继承它的控制器路径最前面是"/api/v1"的就可以省略
而当我们迭代更新

再比如抽象类中用protected修饰公共方法供子类继承,这样子类在需要啥的时候就不能用注入了

其它
  1. 抽象类不可以被实例化

由实现它的子类去实例化

  1. 抽象类有构造函数,但是不能实例化,那么构造函数的意义是什么

在子类构造函数中通过super方法给抽象类的私有属性赋值

  1. 抽象类A继承抽象类B,必须要覆盖父类抽象方法吗?

不用,但如果class C 为最终实现类继承A,则必须实现A和B中所有抽象方法。但是如果不想实现B中的抽象方法,这种情况用抽象类不可以,所以有了接口,jdk1.8后有默认方法

接口(规范约束)

java单继承,多实现
抽象类中定义的抽象方法在子类中必须要实现,并且还不能同时继承多个类。这无疑带来了很多麻烦。所以出现了接口

接口是一种特殊的抽象类

  • 接口中的方法默认全是抽象方法public abstract(可省略)
  • 接口中成员变量默认都是静态常量public static final(可省略)
  • jdk1.8以后允许默认方法和静态方法

抽象类只能单继承,方法必须实现
接口多实现,可同时实现多个接口,不想实现的抽象方法用default修饰加方法体{}即可

default void m1(){
	system.out.print(“接口不实现的方法体”)
}//根据开发需求选择实现

但是,如果此时接口为多实现的话且不同接口有相同的default方法,则实现类必须重写该方法,应为子类不知道该继承哪个接口的方法

抽象类中的非抽象方法可以分担子类的逻辑行为,接口中也有类似的静态方法来分担职责,在子类中使用接口调用,

接口与抽象类

1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法
4.抽象类中的抽象方法的访问类型可以是publicprotected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5.抽象类中可以包含静态方法,接口中不能包含静态方法,JDK1.8以后允许
6.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但 接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7.一个类可以实现多个接口,但只能继承一个抽象类。 单一继承多实现
8.Jdk1.8以后新增了默认方法default和static方法,慢慢替代抽象类的的含义,但是不能完全的消除抽象类。

抽象类中的非抽象方法更多时候起的作用是帮子类分担职责
而接口中类似的则有静态方法

static void m2(){
	return 1;
}

抽象类可以实现接口,接口可以继承多接口。
接口其实也可以new,但是此时它必须自己重写实现自己

枚举(自产自销)

枚举在统一返回与统一异常处理的场景中很适合使用

public enum ConstantsEnum { 
	SESSION_USER,COOKIE_USER;
 }

这个枚举代码相当于一个类自己new自己:

public class ConstantsEnum { 

	ConstantsEnum SESSION_USER = new ConstantsEnum(); 
	ConstantsEnum COOKIE_USER = new ConstantsEnum();
	 
	public ConstantsEnum(){ 
	}
}
  1. 枚举是一个特殊类,可以定义成员变量,定义构造函数
  2. SESSION_USER,COOKIE_USER其实是一个枚举引用,调用枚举类中隐藏的无参构造方法
  3. 枚举不能继承类,不能被new,因为它是自产自销(默认private
  4. 枚举修饰符是private,因为jdk把枚举定义成了一个单例模式
  5. 可自定义普通方法,能实现接口,对其行为约束,可自定义普通方法
  6. 当使用有参构造方法覆盖无参时,SESSION_USER,COOKIE_USER也必须加上参数SESSION_USER(session_user),COOKIE_USER(cookie_user)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月色夜雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值