1.变量
a.变量三要素:变量类型 变量名 作用范围/生命周期
b.变量分为局部变量和成员变量(全局变量、实例变量)
局部变量:声明在方法中或者代码块中的变量称为局部变量。
只在声明当前声明的方法中有效,出了方法之后啥也不是。
代码块:以一个大括号组成的一个代码段称为代码块。
成员变量:声明在类中,类中方法的外面,在整个类当中都有效。
注意:下面的这种报错原因是由于static的问题,而不是成员变量的问题。
在main方法中非static修饰的成员变量,需要在成员变量前加static修饰,如上图,我们需要在int num=6这条语句前面加static修饰,static int num=6;这样程序才不会报错。
当给一个类中的成员变量的类型声明为基本数据类型之后,导致基本数据类型存在默认值。
各个成员变量的默认值:
整型:默认值为0; 浮点型:默认值为0.0;
逻辑型:默认值为false; 字符型:默认值为空格'\u0000'
引用类型:默认值为null
在未赋值的情况下存在值,后续的逻辑可能存在问题
2.方法递归
- 什么是方法递归?
一种编程技巧,在程序中自己调用自己,它由递归头和递归体组成
优势:能够更快的写出代码,复杂度特别低
劣势:特别消耗内存
递归要注意的两点:
递归头:程序在调用自身的过程当中一定要有一个终止环节,亚一定在调用某个环节,程序就不再调用了,相当于有一个出口。
递归体:循环代码
|
执行以上这个程序会发生这样一个错误
java.lang.StackOverflowError SOFE 表示栈内存溢出
递归的使用场景:数据结构和算法当中
注意:
- 凡是可以使用递归程序的都可以使用循环,可以使用循环的不一定可以使用递归。
- 递归必须有结束条件,没有结束条件的一定会发生栈溢出错误,即使有结束条件,而且条件是正确的,也可能发生溢出错误,因为递归太深了。
- 栈帧是可以复用的,能够做到栈帧复用的递归程序称之为尾递归,栈里面保存的是局部变量表
- 可以不使用递归的建议尽量不要使用
3.面向过程与面向对象的理解
面向过程:
要完成一功能时,要将功能分成N个步骤,再按步骤的顺序依次去完成,完成了这N个步骤,整个功能就完成了。重点在于完成这个问题的每一个步骤(过程),它更加精细化处理的具体功能。
面向对象:
对象可以帮助你完成一些功能或者愿望,相当于别人帮你完成了一些功能,你只要去拿来用就行了,至于别人是怎么完成的跟你没有关系。它只关心结果,因此它调用的复杂度降低,但是底层的具体实现思路还是过程式的。
注意:面向对象和面向过程不是相对的,它们是相辅相成的。
类和对象的关系?
类:分门别类。抽象的概念。 祖先为了能够让后来的人更好的去认识这个世界,将各个具象的内容抽离出来一个一个的类。
对象: 将类中所有抽象的内容进行了具象化,现实生活中真实存在的。
类和对象:类是对于对象的抽象,抽象就是抽取像的部分
对象就是对于类的具象化的体现。
先有类还是先有对象?
如果是编写过程: 先有类 再有对象
如果是构建过程: 先有对象,将对象的共性抽离出来,外在、内在->类
4.static的用法
1、static叫做静态的、共享的,它所属于类,类在加载时会优先加载static修饰的内容。
2、static修饰的内容只有一份,被所有的对象以及类共享,对于static修饰的内容改变,也被所有对象可见
3、static修饰的内容两种调用方式:
1.通过类名直接点 类名.(); 推荐使用这一种方法调用
2.通过对象调用 对象.
4、在静态内容中调用非静态的内容,需要在非静态内容中加static。
在main方法中非static修饰的成员变量,需要在成员变量前加static修饰,如上图,我们需要在int num=6这条语句前面加static修饰,static int num=6;这样程序才不会报错。
当创建非静态内容的所属对象时,通过new一个对象去调用,调用时直接(对象.)。
在非静态内容中调用静态方法可以直接调用,方法名();
因为非静态内容隶属于对象,如果非静态内容能够被调用时,对象一定存在,对象存在证明类一定能被加载,而类被加载,静态内容一定被加载。
什么时候类会被加载?
- 调用当前类中的静态方法时
- 创建当前类的实例对象时
5.构造器
- 什么是构造方法?
在类中用来创建对象的那个方法称为构造器(构造方法、构造函数)
b.语法结构:
[修饰符类型] 方法名(形式参数列表){
方法体;
}
作用:构造器就是用来创建对象的,只能通过new关键字去调用。
创建对象的方式:类名 变量名 = new 类名();
Person str = new Person ();//new是用来创建对象的。
当我们遇到new关键字时,在内存中会做三件事:
- 开空间
- 初始化
- 指向引用
式的声明了构造器之后,默认的无参构造器就不在了。
6.this的用法
this. :
可以省略:代表当前对象的(谁在调用代表谁),
不可省略:有同名的变量时,不能省略,为了区分同名变量,局部变量和全局变量
this() :
构造器之间进行互相调用
它必须放在构造器的第一行
7.继承
什么是继承?
子承父业,将多个类中的共同属性集合在一个类当中,其他类可以通过继承去调用这个类中所有的属性和方法,继承的作用是将一些重复的内容不再多写,提高了代码的复用性。
语法结构:
[修饰符列表]class 子类 extends 父类{
}
注意事项:
- java中只支持单继承,一个类中有且仅有一个父类,复用性的提高是有限的。
- 多继承:极大地提高了代码的复用性,但是代码调用的复杂度也提升了
- 单继承:代码调用的复杂度比较低,但是复用性比较有限
- 能不用继承就别用继承
- 当创建子类对象时,会先执行父类中的构造器super的用法
8.super.关键字:
可省略的:当super和this的用法是重复的时候
不可省略:如果子类和父类中出现了同名变量或者是同名方法时
super():调用父类的构造器时,默认情况下是调用父类的无参构造器(默认情况下每个类中都存在一个无参构造器,哪怕不写也存在)
当父类中存在其他构造器时,无参构造器就不存在了,此时如果在子类中没有通过super()显示的指定调用的构造器会导致程序报错。
注意:在构造器中this()和super()不能同时出现,如果两个都不存在,默认是才super()。
9.方法覆盖
什么是方法覆盖?
在子类中定义了和父类中同名的方法,该方法称之为方法覆盖(重写方法)
方法覆盖的作用:当父类的功能不满足子类的需求时,子类可以在父类的基础上进行扩展。
如何确定是否是方法覆盖:在子类的方法上加入@Overried注解,如果不报错,证明是方法覆盖。
方法覆盖的条件:子类的方法名和父类的方法名同名
、参数列表一样、返回类型一样
注意:方法覆盖的前提条件是一定要发生继承关系
10.Object类
Object类是所有类的根基类(超类、父类),当一个类中没有显式的继承关系的时候,默认情况下它的父类都是Object。
Object:
ctrl+O 罗列当前类中的所有方法
finalize: gc回收垃圾时 自动调用finalize
clone: 克隆 (创建对象的一种方式 深浅复制)
hashCode: 哈希码 -> 哈希算法 唯一的值
getClass:获取当前类的Class对象 反射
toString:输出一个对象的时候默认情况下会调用当前对象的toString
== 比较基本数据类型比较的是值 比较引用类型比较的是地址
equals:用来比较相等的 如果相等返回true 反之返回false
Object中的比较是通过==比较的
11.封装
4个关键字的可见性
| 本类 | 同包下子类 | 同包下无关类 | 异包下子类 | 异包下无关类 |
public | 可见 | 可见 | 可见 | 可见 | 可见 |
protected | 可见 | 可见 | 可见 | 可见 | 不可见 |
默认的 | 可见 | 可见 | 可见 | 不可见 | 不可见 |
private | 可见 | 不可见 | 不可见 | 不可见 | 不可见 |
- public表示公开的,公用的,所有类都可以访问
- protected表示受保护的,只在异包下无关类不可访问
- 默认的,在异包下所有类都不可访问
- Private表示私有的,只能在本类中显示
修饰符的作用是用来屏蔽一些底层的实现逻辑,降低调用者(程序员)的复杂度。
* 确保当前类更加安全。
* 修饰符可以修饰 类
* 属性(成员变量) :
* 避免随意.属性,修改获取属性 造成数据不安全
* 如果用private修饰的话 一定要保证对外提供get、set
方法让外部课件
* 方法
* 屏蔽底层调用细节,降低调用者(程序员)的复杂度 使得代码
更加健壮
封装的步骤:
- 所有属性私有化,修饰符用private
- 对外提供简单的操作入口
-对外提供两个公开的方法,get和set方法
get :获取属性
set : 修改属性