Java 标识符由数字,字母和下划线_,美元符号$组成。在 Java 中是区分大小写的,而且还要求首位不能是数字。
Java 中的变量类型如下:
数据类型 | 默认值 | 存储格式 | 数据范围 |
---|---|---|---|
short | 0 | 2个字节 | -32,768到32767 |
int | 0 | 4个字节 | -2,147,483,648到2,147,483,647 |
byte | 0 | 1个字节 | -128到127 |
char | /u0000 | 2个字节 | Unicode的字符范围 |
long | 0L或0l | 8个字节 | -9,223,372,036,854,775,808到9,223,372,036, 854,775,807 |
float | 0.0F或0.0f | 4个字节 | 32位IEEEE 754单精度范围 |
double | 0.0或0.0D(d) | 8个字节 | 64位IEEE 754双精度范围 |
boolean | false | 1位 | true(1)或false(0) |
自动类型转换需要满足下面的两个条件:
目标类型与原类型兼容
目标类型的字节数大于或等于原类型字节数
一般常量有两种意思:
第一种意思就是这个值本身,如一个整数9,我们就说是“一个int类型的常量9”。当然还有实数常量3.14,字符常量‘a’等等。
另一种常量便表示不可变的变量,就是我们在变量声明前加上了 final 关键字。比如:final int i=0;那么这个i的值便不能被修改。
当我们声明了数组后,需要为数组分配空间,也就是定义多大的数组。
int [] ages = {12,18,9,33,45,60}; //声明并初始化了一个数组,它有6个元素
char [] symbol = new char[10] //声明并分配了一个长度为10的char型数组
for 语句在数组内可以使用特殊简化版本,在遍历数组、集合时,foreach 更简单便捷。
int [] ages = {12, 18, 9, 33, 45, 60};
int i = 1;
for(int age:ages){
System.out.println("数组中第"+i+"个元素是"+age);
i++;
}
this关键字代表当前对象。使用this.属性操作当前对象的属性,this.方法调用当前对象的方法。
内部类
内部类的主要作用如下:
内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
内部类的方法可以直接访问外部类的所有数据,包括私有的数据
内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
内部类 对象名 = 外部类对象.new 内部类();
静态内部类
静态内部类是 static 修饰的内部类,这种内部类的特点是:
静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
如果外部类的静态成员与内部类的成员名称相同,可通过类名.静态成员访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过成员名直接调用外部类的静态成员
创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();
方法内部类
方法内部类就是定义在外部类的方法中的内部类,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
在 Java 中一个类只有一个父类,所以 Java 中的继承是单继承。
重写的方法一定要与原父类的方法语法保持一致,比如返回值类型,参数类型及个数,和方法名都必须一致。
继承的初始化顺序是先初始化父类再初始化子类。
final关键字可以修饰类、方法、属性和变量
final 修饰类,则该类不允许被继承
final 修饰方法,则该方法不允许被覆盖(重写)
final 修饰属性:则该类的属性不会进行隐式的初始化(类的初始化属性必须有值)或在构造方法中赋值(但只能选其一)
final 修饰变量,则该变量的值只能赋一次值,即变为常量
static代码块
JVM加载类时会按顺序执行这些静态的代码块,只会执行一次,可以对一些static变量进行赋值。
public class Test{
private static int a;
static{
a = 1;
}
}
super关键字在父类内部使用,代表父类对象。
访问父类的属性 super.属性名
访问父类的方法 super.bark()
多态
引用多态
父类的引用可以指向本类的对象。
Animal a = new Animal(); //a是父类的引用指向的是本类的对象
Animal b = new Dog(); //b是父类的引用指向的是子类的对象
//注意:我们不能使用一个子类的引用去指向父类的对象
方法多态
在多态中,创建子类对象时,调用的方法为子类重写的方法或继承的方法。
Animal a = new Animal(); //a是父类的引用指向的是本类的对象
Animal b = new Dog(); //b是父类的引用指向的是子类的对象
//这边是引用的多态
a.bark(); //调用的是父类Animal的方法
b.bark(); //调用的是子类Dog重写的方法
//这便是方法的多态
注意:
- 父类分引用指向子类对象时不可以调用子类独有的方法,只能调用继承或重写的方法
- 引用多态不能使用一个子类的引用去指向父类的对象
多态引用类型转换
向上类型转换(隐式/自动类型转换)
是小类型到大类型的转换(无风险)
向下类型转换(强制类型转换)
是大类型到小类型(有风险)
Dog a = new Dog();
Animal b = a; //自动类型提升 向上类型转换(无风险),没有改变对象本质,只是变成父类引用
/*
Dog c = b;
//将父类引用转换成子类引用,编译器不允许这样做
*/
Dog c = (Dog)b; //在父类前加上小括号,里面加上子类类型,实现强制转换
//向下类型转换
/*
Cat d = (Cat)b;
//虽然编译器不会报错,但运行会出问题,因为b是指向Dog类的,它们是不同类型的对象,这里就存在风险
/*
抽象类
抽象类是限制规定子类必须实现某些方法,但不关注实现细节。
用 abstract 修饰符定义抽象类
用 abstract 修饰符定义抽象方法,只用声明,不需要实现
包含抽象方法的类就是抽象类
抽象类中可以包含普通的方法,也可以没有抽象方法
抽象类的对象不能直接创建,我们通常是定义引用变量指向子类对象。
//抽象方法
public abstract class TelePhone {
public abstract void call(); //抽象方法,打电话
public abstract void message(); //抽象方法,发短信
}
public class CellPhone extends TelePhone {
@Override
public void call() {
// TODO Auto-generated method stub
System.out.println("我可以打电话!");
}
@Override
public void message() {
// TODO Auto-generated method stub
System.out.println("我可以发短信!");
}
}
注: @ Override
是伪代码,表示重写,编译器可以做检查。