本周学习时间较少,于是在此将之前学过的一些内容也一并总结一下。
一、数据类型转换
1.八种基本数据类型除布尔类型之外剩下的七种类型之间都可以相互转换。
2.小容量向大容量转换,为自动类型转换。
byte<short<int<long<float<double
char <
char和short可表示的种类数量相同,但char可取更大的正整数。
3.大容量向小容量转换,为强制类型转换。
转换时,需加强制类型转换符。但在运行阶段可能会损失精度。
4.当int型字面值没有超出byte,short,char的取值范围时,可以直接赋值给byte,short,char类型的变量。
5.byte,short,char混合运算时,各自先转换成int类型再做运算。
6.多种数据类型混合运算,先转换成容量最大的那种类型再做运算。
二、JVM的主要三大内存空间
1.方法区内存(静态变量):在类加载的时候,class字节码代码片段被加载到该内存空间当中。
2.栈内存(局部变量):方法代码片段执行的时候,会给该方法分配内存空间,在栈内存中压栈。
3.堆内存(实例变量):new的对象在堆内存中存储。成员变量中的实例变量(也称对象变量)在堆内存的java对象内部存储。
4.三块内存当中变化最频繁的是栈内存,最先有数据的是方法区内存,垃圾回收器主要针对的是堆内存。
5.垃圾回收器【自动垃圾回收机制:GC机制】
问题:什么时候会考虑将某个Java对象的内存回收?
答:没有更多的引用指向堆内存中的Java对象时,这个对象无法被访问(对象只能通过引用的方式访问),会变成垃圾。
当堆内存中的Java对象成为垃圾数据时,会被垃圾回收器回收。
(图片来自b站动力节点)
三、静态成员与实例成员
1.静态成员/类成员(前边修饰符有static):类的所有对象在类的范围内共享的某个成员,不属于任何由此类产生的成员。
2.实例成员/对象成员(前边修饰符没有static):在类中定义的由此类产生的对象所拥有的成员。只有创建了对象之后,才能通过对象访问实例成员变量、调用实例成员方法。
四、关于方法
1.方法编写的位置没有先后顺序,可以随意。
2.方法体中不能再定义方法。
3.方法名前的修饰符有“static”时,用“类名.方法名”调用;方法名前的修饰符没有“static”时,用“引用.方法名”调用。
4.方法重载只和“方法名+类型”有关,与修饰符列表和返回值类型无关。
5.方法递归十分消耗栈内存,不建议使用。
public class 方法递归 {
public static void main(String[] args){
int n = 4;
int retvalue = method(n);
System.out.println(retvalue);
}
public static int method(int n){
if (n == 1)
return 1;
else
return n * method(n - 1);
}
}
6.构造方法
1.构造方法不需要指定返回值类型(因为它的返回值类型已经确定,就是构造方法所在类的类型),也不能写“void”。一旦写上void,这个方法就变成了普通方法,并且也不需要写return语句,Java程序自动返回值。
2.构造方法的方法名必须和类名保持一致。
3.构造方法的作用:
*通过构造方法的调用,可以创建对象。
*创建对象的同时,初始化实例变量的内存空间。
4.构造方法的调用:new 构造方法名(实参列表)。
5.当一个类中没有定义任何构造方法的话,系统默认给该类提供一个无参数的构造方法,这个构造方法被称为“缺省构造器”。
6.构造方法支持重载机制,在一个类中可以定义多个构造方法。
六、从软件的开发的生命周期来看,基于面向对象的三个阶段:
1.面向对象的分析(OOA)
2.面向对象的设计(OOD)
3.面向对象的编程(OOP)
七、面向对象的三大特征
1.封装
封装就是把过程和数据包裹起来,对数据的访问只能通过已经定义的接口。
隐藏对象内部的复杂性、只对外公开简单的接口。便于外界调用从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来,这就是封装的设计思想。在Java中通过权限修饰符关键字private、protected和public实现封装。
2.继承
(1)继承的作用:
*代码复用。
*最重要的作用:有了继承才有了以后的“方法的覆盖”和“多态机制”。
(2)语法格式:
[修饰符列表] class 类名 extends 父类名 {
类体 = 属性 + 方法
}
(3)Java语言当中只支持单继承,即一个类不能继承多个类,只能继承一个类。但一个类可以间接继承多种其它类。
(4)继承当中的一些术语:
B类继承A类,其中:
A类称为:父类,基类,超类,superclass
B类称为:子类,派生类,subclass
(5)子类继承父类哪些数据?
私有的和构造方法不支持继承,其它数据都可以被继承。
(6)方法覆盖/方法重写
*当父类中的方法已经无法满足子类的需求,子类将父类中继承过来的方法重新进行编写,这个重新编写的过程叫做方法覆盖/方法重写。
*方法重载发生在具有继承关系的父子类之间,返回值类型相同,方法名相同,形参列表相同。访问权限不能更低,可以更高。
*注意:私有方法不能继承,所以不能覆盖。
构造方法不能继承,所以不能覆盖。
静态方法不存在覆盖。
覆盖只针对方法,不谈属性。
3.多态
(1)语法机制:
1.子类向父类转换,称为向上转换/自动类型转换/upcasting
父类型引用指向子类型对象这种多态语法机制导致程序存在“编译阶段绑定”和“运行阶段绑定”两种不同的形态/状态。
2.父类向子类转换,称为向下转换/强制类型转换/downcasting
什么时候需要使用向下转型:当使用的方法是子类型中特有的,在父类型当中不存在,必须进行向下转型。
3.无论是向上转型还是向下转型,两种类型之间都必须有继承关系。没有继承关系,程序无法编译通过。
这里放一个例子说明一下多态的使用。
public class Animal {
public void move(){
System.out.println("动物在移动");
}
}
public class Bird extends Animal {
public void move(){ // 重写父类继承过来的方法
System.out.println("鸟儿在飞翔");
}
}
public class Cat extends Animal {
public void move(){ // 重写父类继承过来的方法
System.out.println("猫在走猫步");
}
public void catchMouse(){ //子类对象特有的方法
System.out.println("猫抓老鼠");
}
}
public class Test {
public static void main(String[] args){
//向上类型转换,父类型引用指向子类型对象
Animal a1 = new Cat();
a1.move();
/*
* 在编译阶段,编译器检查a1这个引用的数据类型为Animal,由于Animal.class字节码
* 中有move方法,所以编译通过了。这个过程称为静态绑定,或编译阶段绑定。只有静态绑定
* 过后才有之后的运行。
* 在程序运行阶段,JVM堆内存当中真实创建的对象是Cat对象,那么程序在运行阶段调用的
* 是Cat当中的move方法。这个过程称为动态绑定,或运行阶段绑定。
*/
//向下类型转换,强制类型转换,需加强制类型转换符
/*
a1.catchMouse(); 由于Animal.class字节码中没有该方法,所以编译无法通过。
若想调用catchMouse方法,可以将a1强制类型转换成Cat类型。
*/
Cat a2 = (Cat) a1;
a2.catchMouse();
Animal a3 = new Bird();
Cat a4 = (Cat) a3;
/*
* 以上程序编译可以通过,因为Animal和Cat之间存在继承关系。
* 但程序在运行阶段会出现问题,因为JVM堆内存中真实存在的对象是Bird类型,Bird对象
* 无法转换成Cat对象,因为两种类型之间不存在继承关系,此时出现了著名的异常:
* java.lang.ClassCastException (类型转换异常)
* 这种异常总是在“向下转型”的时候发生。
*/
if (a3 instanceof Cat){
Cat c1 = (Cat) a3;
c1.catchMouse();
} else if (a3 instanceof Cat) {
Bird b1 = (Bird) a3;
}
}
}
本周的总结就到这里。