JAVA基础(三)
类与对象
1、类是抽象的,概念的,代表一类事物。
2、对象是具体的,实际的,代表一个具体事物 即实例。
3、类是对象的模板,对象是类的一个个体,对应一个实例。
属性=成员变量=字段(field)
属性如果不赋值,有默认值,规则和数组一样。具体说: int 0 short 0 byte 0 long 0 float 0.0 double 0.0 char \u0000 boolean false String null
Java内存的结构分析
栈:一般存放基本数据类型(局部变量)
堆:存放对象(Object boject ,数组等)
方法区:常量池(常量,比如字符串),类加载信息。
递归调用
简单的说:递归就是方法自己调用自己,每次调用的传入不同的变量。
递归调用的重要原则:
1、执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
2、方法的局部变量是独立的,不会相互影响,比如n变量
3、如果方法中使用的是引用类型变量(比如数组、对象),就会共享该引用类型的数据。
4、递归必须向退出递归条件逼近,否则就是无限递归。
5、当一个方法执行完毕,或者遇到return,就会返回,遵循谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。
斐波那契数列:
public int fibonacci (int n){
if( n >= 1){
if ( n == 1 || n == 2){
return 1;
} else {
return fibonacci(n-1) +fibonacci(n-2);
}
}else{
System.out.println("需要输入n");
return -1;
}
}
汉诺塔:
class Tower{
//方法
//num 表示要移动的个数,a,b,c 分别表示A,B,C 三个塔
public void move(int num,char a ,char b , char c){
if(num == 1){//如果只有一个盘 num=1
System.out.println(a + "->" + c);
}else{
//如果有多个盘,可以看成两个,最下面的和最上面的所有盘(num - 1)
//先移动上面所有的盘到b,借助 c
move(num - 1, a,c,b);//记得最下面的这个盘移动到c
System.out.println(a +"->" + c);
move(num - 1,b ,a , c);//把b塔所有盘,移动到c,借助a
}
}
}
方法重载:
Java 中允许同一个类中,多个同名方法的存在,但要求形参列表不一致。
方法名必须一样;形参列表必须不同(形参类型或个数或顺序,至少有一样不同,参数名无要求),返回类型无要求。
advantage:1、减轻了起名的麻烦。2、减轻了记名的麻烦。
可变参数:(Variable parameters)
本质:数组
java允许将同一个类中多个同名同功能但参数不同的方法,封装成一个方法。
访问修饰符 返回类型 方法名 (数据类型. …形参名){
}
public int sum(int... nums){//int... 表示接受的是可变参数,类型是int,即可以接受多个int(0-多)
//使用可变参数时,可以当作数组使用,即nums可以当作数组
//遍历nums 求和即可
}
作用域:
1、属性和局部变量可以重名,访问时遵循就近原则。
2、在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。
3、属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量,生命周期较短,伴随着它的代码块的执行二创建,伴随着代码块的结束二销毁,即在一次方法调用过程中。
4、作用域范围:全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
局部变量:只能在本类中对应的方法中使用。
5、修饰符不同:全局变量/属性可以加修饰符(private、protected、public…)
局部变量不可以加修饰符
构造器/构造方法
基本语法: [修饰符]方法名(形参列表){
方法体; }
1、构造器的修饰符可以默认,也可以是 public、protected、private
2、构造器没有返回值,构造器名和类名要相同
3、方法名 和类字名必须一样
4、参数列表和成员方法一样的规则
5、构造器的调用系统的完成。
6、如果没有定义构造器,系统自动给类生成一个默认的无参构造器。
7、一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参够造器,除非显式的定义以下。
this关键字
1、this关键字可以用来访问本类的属性、方法、构造器
2、this用于区分当前类的属性和局部变量
3、访问成员方法的语法:this.方法名(参数列表)
4、访问构造器语法:this(参数列表); 注:只能在构造器中使用(只能在构造器中访问另一个构造器)。
5、this不能在类定义的外部使用,只能在类定义的方法中使用。
6、 访问构造器语法: this(参数列表);必须放置第一条语句
包的命名:
规则:只能包含数字、字母、下划线、小圆点,但不能用数字开头,不能是关键字或保留字。
命名规范:一般是小写字母+小圆点一般是: com.公司名.项目名.业务模块名。
常用的包:
java.lang.* //lang包是基本包,默认引入 ,不需要再引入
java.util.*//util 包,系统提供的工具包,工具类,使用Scanner
java.net.*//网络包,网络开
java.awt.*//是做java的界面开发。GUI
访问修饰符:用于控制方法和属性(成员变量)的访问权限(范围)
访问级别 | 访问控制修饰符 | 同(本)类 | 同包 | 子类 | 不同包 |
---|---|---|---|---|---|
公开 | public | √ | √ | √ | √ |
受保护 | protected | √ | √ | √ | × |
默认 | 没有修饰符 | √ | √ | × | × |
私有 | private | √ | × | × | × |
面向对象的三大基本特征:继承、封装、多态
封装:就是把抽象出的数据(属性)和对数据的操起(方法)封装在一起,数据被保护在内部,程序的其他部分只通过被授权的操作(方法),才能对数据进行操作。
1、将属性进行私有化private(不能直接修改属性)
2、提供一个公共的(public)set方法,用于对属性判断并赋值
3、提供一个公共的get方法,用于获取属性的值
继承:
1、子类继承了所有的属性和方法,非私有的属性和方法可以在子类中直接使用,但是私有属性和方法不能再子类直接访问,要通过公共的方法去访问。
2、子类必须调用父类的构造器,完成父类的初始化。
3、当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super()去指定使用父类的哪个构造器完成对父类的初始化工作。
4、如果希望指定去调用父类的某个构造器,则显示的调用一下。
5、super在使用时,必须放在构造器的第一行(super 只能在构造器中使用)。
6、super()和 this() 都只能放在构造器的第一行,因此这两个方法不能共存在一个构造器中。
7、Java所有类都是Object类的子类,Object是所有类的基类。
8、父类构造器的调用不限于直接父类!将一直往上追溯到Object类。
9、子类最多只能继承一个父类,即Java中是单继承机制。
10、不能滥用继承,子类和父类必须满足 is - a 的逻辑关系。
super关键字
super代表父类的引用,用于访问父类的属性、方法、构造器。
1、访问父类的属性,但不能访问父类的private属性
2、访问父类的方法,不能访问父类的private方法 super.方法名(参数列表);
3、访问父类的构造器 super(参数列表);只能放在构造器的第一句。
super和this 比较:
区别点:
访问属性:this :访问本类中的属性,如果本类没有此属性从父类中继续查找。
super:从父类开始查找方法。
调用方法:this 访问本类中的方法,如果本类没有此方法从父类中继续查找。
super:从父类开始查找方法。
调用构造器:this 调用本类构造器,必须放在构造器首行。
super:调用父类构造器,必须放在子类构造器首行。
特殊:this 表示当前对象
super:子类访问父类当对象。
方法的重写/覆盖:子类有一个方法,和父类的某个方法的名称,返回类型、参数一样。
1、子类的方法的参数,方法名称,要和父类方法的参数,方法名称完全一样。
2、子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类。比如 父类 返回类型是Object,子类方法返回类型是String
3、子类方法不能缩小父类方法的访问权。public >protected>默认>private
名称 | 发生范围 | 方法名 | 形参列表 | 返回类型 | 修饰符 |
---|---|---|---|---|---|
重载 | 本类 | 必须一致 | 类型、个数或者顺序至少一个不同 | 无要求 | 无要求 |
重写 | 父子类 | 必须一致 | 相同 | 子类重写的方法,返回类型和父类返回类型一致或者是其子类 | 子类方法不能缩小父类方法的访问范围 |
多态
1、方法的多态
2、对象的多态
1、一个对象的编译类型和运行类型可以不一致
2、编译类型在定义对象时,就确定了,不能改变了
3、运行类型是可以变化的
4、编译类型看定义时 = 号的左边,运行类型看 = 号 的右边
多态的前提是:两个对象存在继承关系
多态的向上转型
1、本质:父类的引用指向子类的对象
2、语法:父类类型 引用名 = new 子类类型();
3、特点:编译类型是左边,运行类型看右边。可以调用父类中的所有成员(需遵循访问权限),不能调用子类中特有成员;
多态向下转型:
1、语法:子类类型 引用名 = (子类类型) 父类引用;
2、只能强转父类的引用,不能强转父类对象
3、要求父类的引用必须指向的是当前目标类型的对象
4、向下转型后,可以调 用子类类型中所有的成员。
eg:
{
//属性没有重写之说;属性的值看编译类型
Base base = new Sub();
System.out.println(base.count);//看编译类型 10
Sub sub = new Sub();
System.out.println(sub.count);//20
}
class Base {
int count=10;
}
class Sub extends Base{
int count = 20;
}
instanceof :用于判断类型是否为XX类型或XX类型的子类型
java动态绑定机制:
编译类型(父类) = new 运行类型(子类) ,运行类型是根据实际情况有JVM来判断的。
1、当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定。
2、当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用。
Object 详解
== 和 equals 的对比
==是一个比较运算符
1、 == 判断基本数据类型 、判断引用数据类型
2、如果判断基本数据类型 ,判断的是值否相等
3、如果判断引用类型,判断的是是否地址相等,即判定是不是一个对象。
4、equals :是Object 类中的方法,只能判断引用类型。
5、默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等
hashCode方法:
1、提高具有哈希结构的容器的效率。
2、两个引用,如果指向的是同一对象,则哈希值肯定是一样的。
3、两个引用,如果指向的是不同对象,则哈希值是不一样的。
4、哈希值主要根据地址号来的!不能完全将哈希值等价于地址。
5、后面在集合,中hashCode 如果需要的话,也会重写,在讲解集合时。
toString方法:
基本介绍:默认返回:全类名+@+哈希值的十六进制,子类往往重写toString方法,用于返回对象的属性信息。
重写toString 方法,打印对象或拼接对象时,都会自动调用该对象toString形式。
当直接输出一个对象时,toString方法会默认的调用
getClass().getName() //类的全类名(包名+类名)
finalize方法
1、当对象被收回时,系统自动调用该对象的finalize方法,子类可以重写该方法,做一些释放资源的操作。
2、什么时候被收回:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就是使用垃圾回收机制销毁对象,在销毁对象前,会调用finalize方法。
3、垃圾回收机制的调用,是由系统决定(即有自己的GC算法),也可以通过System.gc() 主动出发垃圾回收机制。