一、变量及标识符
Java 标识符规则
● 定义:有字母、数字、_、$组成的 ● 最基本的定义:以英文字母开头 ● 大小写敏感 ● 标识符不得和关键字重复 ● 不能以数字开头,不能使用空格分隔 ● 长度无限制 ● 常量记得赋初值
注释
注释主要起解释说明的作用、可以有效的增强程序的可读性和可维护性、Java语言支持三种格式注释:单行注释、区域注释、文档化注释。
单行注释:以“'
区域注释:以“/ ”开始,** “/”结束,中间可以跨多行注释内容
文档注释:以“/ ”开始,***“/”结束,中间可以跨行注释内容
会显示绿色的注释
文档注释,会显示蓝色的注释
变量的定义
- 变量的定义由变量类型和变量名(标识符)
- 变量的声明就是一条完整的 Java语句,必须在结尾处用分号
二、数据类型
Java数据类型中分为 基本数据类型 和 引用数据类型 两大类 ● 基础数据类型 (8种) 整形:byte、short、int、long(整数) —> 默认值 0 浮点型:float、double(带小数点的数值类型) —> 默认值 0.0 字符型:char(使用单引号【’】包含的字符) —> 默认值 “\u0000” (Java 10) 布尔型:boolean(使用true or false表示的数据值)—> 默认值 false ● 引用数据类型 ○ 除了 基础数据类型 之外都是 引用类型 ○ 包括 API 中的类:比如 String、File ○ 也包括自定义的类,比如 Person,Student ○ 数组 int [], String [], 接口等等
整形数据范围 byte < short < int < long
类型 | 储存需求 | 取值范围 |
---|
byte | 1字节 | -128~127 | short | 2字节 | -32,768~32767 | int | 4字节 | -2^31 - 2^31 -1 | long | 8字节 | -2^63 - 2^63 -1 | char | 16 | 0~65536 |
浮点型
类型 | 储存需求 | 取值范围 |
---|
float | 4字节 | ±3.40282347E+38F | double | 8字节 | ±1.79769313486231570E+308 |
引用数据类型使用
● 引用数据类型使用的场景与基本数据类型 完全一样 ○ 作为属性的类型 ○ 作为方法的返回值类型使用 ○ 作为方法的形式参数类型使用 ● 应用类型的赋值 ○ 引用类型都是对象,所以赋值都是使用 new 调用构造方法进行赋值 ○ 例外:String 类可以直接使用 = 赋值
eg:String 字符串 (双引号) String 类的存在,可以用普通字符串形式进行赋值 Java 中,数据范围大的数据类型与数据范围小的数据类型进行运算的时候,会自动转换为大类型,比如double 类型和 int 类型计算,结果会变成double类型,如果这两者和String 运算,就会变成 String 类型 如果是 char 类型,必须使用 单引号
public class Test{
public static void main(String [] args){
String str = "hello World";
System.out.print(str/打印 hello World
String s = "1" + str;
System.out.print(str/打印 1ello World
}
}
基本类型 与 引用类型的区别
| 基本数据类型 | 引用数据类型 |
---|
概念 | 变量(单纯的值) | 对象(引用的) | 存储位置 | 在栈存值 | 栈中存引用,在堆中存具体的对象属性值 | 赋值方式 | 直接赋值 | new,String类和包装器类可以直接赋值 |
ps:包装器类-----java 使用简单的数据类型,例如整型(int ) 和字符型 (char )。这些数据类型不是对象层次结构的组成部分。他们通过值传递给方法而不能直接通过引用传递。 有时需要对这些简单的类型建立对象表达式,例如,当把数据放到集合中时,需要包装成对象。为了能够用对象的形式代表简单数据类型, java提供了与 每一个 简单类型相应的类。从本质上讲,这些类中包装了(Wrap)简单类型的数据。因此,它们通常被称作类型包装器或者包装类。
成员变量 和 局部变量
概念及区别
-
在类中位置不铜 成员变量 类中方法外 局部变量 方法内或者方法声明上 -
在内存红位置不同 成员变量 堆内存 局部变量 栈内存 -
生命周期不同 成员变量 随着对象的存在而存在,随着对象的消失而消失 局部变量 随着方法的调用而存在,随着方法的调用完毕而消失 -
初始化值不同 成员变量 有默认的初始值 局部变量 没有默认的初始值,必须先定义、赋值、再使用
public class People{
int num;
void test(int n1) {
int n2 = 1;
}
}
三、Java 类的基本结构
类的结构
● 属性:对象数据的描述 ● 方法:对象的行为(可以做哪些事) ● 构造方法:用于实例化对象 ● 内部类:(inner class)即在类体中声明的类 ● 块:分为静态块(static),实例块(局部代码块)
public class Person{
String name;
int age;
public Person() {
...
}
public void eat() {
System.out.println('吃饭');
}
{
System.out.println('我是实例块');
}
static {
System.out.println("我是静态块");
}
class InnerClass {
}
}
执行顺序
- 父类 静态代码块,静态代码块 ps:按照声明是顺序执行
- 子类 静态代码块,静态变量 ps;按照声明顺序执行
- 父类局部代码块,成员变量;ps 按照顺序执行
- 父类构造函数
- 子类局部代码块,成员变量 ps,按声明顺序执行
- 子类构造函数
Java 中类的声明及作用
Java 类中的声明形式:
【访问权限修饰符】 【修饰符】class 类名 { 类体 }
属性的声明及作用:
【访问权限修饰符】 【修饰符】数据类型 属性名 = 【初值】
例:
public class Student {
String stuName;
private static int age = 18;
private double avgScores;
.....
}
方法的声明格式:
【访问权限修饰符】 【修饰符】 返回值类型 方法名 (形参列表,..) {
方法体;
return 返回值;
}
方法修饰符权限范围:
方法重载
方法重载的三大法则:
- 方法名相同
- 参数不同
a. 数量不同 b. 数据类型不同 c. 顺序不同 - 同一作用域
注意: - 当返回值不一样时,就无法构成重载
- 必须要在同一个类当中
构造方法的声明形式及作用
构造方法的作用:对象实例化时使用,创建对象时使用,所以构造方法是一个类不可缺少的的一个方法 构造方法 与 方法的区别
构造方法:
- 在实例化对象的时候调用
- 没有返回值,不用加 void
- 方法名必须与类名相同
- 不能使用修饰符:static、final、abstact
方法: 5. 有静态方法 和 非静态方法 6. 可以使用修饰符:static、final、abstract 7. 静态方法可以直接由类名直接调用,非静态方法需要对象调用 8. 返回值可无,但是要加 void 9. 方法名最好不和类名一样
ps:
- 构造方法是通过 new 关键字调用的
- 构造方法的特性
a. 构造方法的方法名必须与类名一致 b. 形参可以无 c. 构造方法有一个默认的无参构造方法,当我们声明了一个构造方法,这个默认的无参构造方法就会被重载
块与内部类
块在类中声明,类似一个没有方法声明的方法体,分为实例块 和 静态块
实例块:
作用:每次调用构造方法前自动调用
{
}
静态块
类加载时被调用,仅一次,与是否创建对象无关
static {
}
内部类
内部类:在类内部定义的类,不能在方法内部 内部类可以直接调用外部类的属性,往往在 GUI 中使用的比较多 Java内部类可分为成员内部类、局部内部类、匿名内部类、静态内部类。
成员内部类
成员内部类可以看成是外部类的一个成员,在成员内部类中无法声明静态成员。 但staticfinal字段是个例外。我们知道加载类时,会先初始化静态成员,如果成员内部类有静态成员,那么内部类就会在外部类之前生成,而内部类是为外部类服务的,内部类在外部类之前就生成可能会脱离掌控。 所以在实例化成员内部类时,成员内部类会持有一个外部类当前对象的引用,这样在成员内部类中就可以直接访问外部类的成员,即使是private修饰的。
public class Outter {
private String outname="out";
private int age;
private Inner inner = new Inner();
class Inner {
private String innername="in";
public void test() {
System.out.println(outname);
}
}
}
局部内部类
局部内部类的使用和成员内部类的使用基本一致,只是局部内部类定义在外部类的方法中,就像局部变量一样,并不是外部类的成员。 局部内部类在方法外是无法访问到的,但它的实例可以从方法中返回,并且实例在不再被引用之前会一直存在。局部内部类也可以访问所在方法的局部变量、方法参数等,限制是局部变量或方法参数只有在声明为final时才能被访问。
public class Outer {
private String outName = "out";
public void show(final String str){
class Inner{
public void print(){
System.out.println(outName+str);
}
}
Inner inner = new Inner();
inner.print();
}
public static void main(String[] args) {
Outer out = new Outer();
out.show("lalala");
}
}
匿名内部类
可以把匿名内部类想象成是没有类名的局部内部类,匿名内部类有以下特点:
1、匿名内部类不能有构造器,匿名内部类没有类名,肯定无法声明构造器。
2、匿名内部类必须继承或实现一个接口,指定给new的类型为匿名类的超类型,匿名类不能有显示的extends或implements子句,也不能有任何修饰符。
3、匿名内部类和成员内部类、局部内部类一样,也不能声明静态成员。
public class Outer {
private String outName = "out";
public void show(final String str){
new Inner(){
public void print(){
System.out.println(outName+str);
}
}.print();
}
}
interface Inner{
void print();
}
静态内部类
静态内部类,有的书上也称为嵌套类,声明它时需要用static修饰符,静态内部类不同于前三种内部类,静态内部类不会持有外部类当前对象的引用,所以在静态内部类中无法访问外部类的非静态成员,可以这么说,静态内部类不依赖于外部类。
类加载的生命周期
- 静态变量
- 静态代码块
- 成员变量
- 实例代码块
- 构造方法
类关联类结构
● 关联关系 (一对一、一对多) ● 依赖关系(A用了另一个类B) ● 继承关系 ● 实现关系(本质也是继承关系)、接口的关系
继承
所谓继承是指一个类的定义可以基于另外一个已经存在的类,即子类基于父类,从而实现父类代码的重用,子类能吸收已有类的数据属性和行为,并能扩展新的能力。
public class Animal {
private String name;
public void eat(){
System.out.println("eat!");
}
public void run(){
System.out.println("run!");
}
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
子类:
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
public void wang(){
System.out.println("wang!wang!wang!");
}
public static void main(String[] args) {
Dog dog = new Dog("wang");
dog.eat();
dog.wang();
}
}
ps: ● 子类构造方法总是先调用父类构造方法 ● 默认情况下,调用父类无参构造方法 ● 可以在子类构造方法第一行,使用 super() 关键字调用父类任意一个构造方法
方法的重写(覆盖)
● 重写:如果父类的方法无法满足子类的使用,那么子类可以使用同名方法覆盖父类方法 ● 要求:方法名一致,参数列表一致,返回名一致、访问修饰符不能比父类的权限小
多态
- 必须有继承(或者实现的接口)
- 必须有子类对象获取父类的引用
- 必须有子类对父类的方法进行重写
多态性
● 多态性是面向对象三大特征之一 ● 多态的含义:对外一种表现形式,内部有多种具体实现 ● 多态的体现 ○ 方法的重载 ○ 方法覆盖 ○ 多态参数 我们创建对象一般是 类名 名 = new 类名(); ● 等号左边称为编译期 ● 等号右边称为运行期
A a = new A();
a.show();
A ab = new B();
ab.show();
B b = (B)ab;
对于后面的方法:编译类型是父类,运行期是子类,被称为父类引用指向子类的对象。 因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特, 定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。
所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;同时,父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用; 对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。也可以叫做动态绑定。 动态绑定是指”在执行期间(而非编译期间)“判断所引用对象的实际类型,根据实际的类型调用其相应的方法。
多态环境下的调用
对成员方法的调用
class Animal{
void show() {
System.out.println("Animal");
}
}
class Cat extends Animal {
void show() {
System.out.println("Cat");
}
}
...
Animal x = new Cat();
x.show();
编译看左边,运行看右边 对静态方法的调用:
class Animal{
static void show() {
System.out.println("Animal");
}
}
class Cat extends Animal {
static void show() {
System.out.println("Cat");
}
}
...
Animal x = new Cat();
x.show();
编译和运行看左边 对成员变量法的调用:
class Animal{
int num = 3;
}
class Cat extends Animal {
int num = 4;
}
...
Animal x = new Cat();
x.num;
编译和运行都看等号左边 ps:变量不存在被子类覆盖的说法,只有方法存在覆写
多态环境下的对象造型
class Animal{
abstract void eat();
}
class Cat extends Animal{
void look() {
System.out.println("看家");
}
}
...
Animal x = new Cat();
x.eat();
x.look();
instanceof 操作符
instanceof 是判断对象类型的,常用来判断一个对象类是否为一个特定对象的实例
result = 对象名称 instanceof 类型
class Person {
...
}
Person p = new Person();
boolean result = Person instanceof p;
抽象
● 如果一个类中没有包含足够的信息来描述一个具体的对象,这样的类就是抽象类 ○ 比如形状类就是抽象类,圆形,三角形就是具体的类 ● 用 abstract 修饰的类就是 抽象类。如果某个类中包含有抽象方法那么该类必须定义为 抽象类 ,但是抽象类不一定有抽象方法 ● 抽象类可以有 成员属性 和 非抽象成员方法 ● 抽象类不能被实例化,但是可以有构造函数 ● 抽象类只能用作基类,表示的是一种继承关系。继承抽象类的非抽象类必须实现其中的所有抽象方法,而已实现方法的参数、返回值要和抽象类中的方法- -样。否则,该类也必须声明为抽象类。 例:
public abstract class Shapes {
public abstract void draw();
}
public abstract class Shapes{
public void draw() {
}
}
ps:
- 抽象类可以有构造方法,但不能直接实例化,只能用来继承;
- 抽象类的派生子类应该提供对其所有抽象方法的具体实现如果抽象类的派生子类没有实现其中的所有抽象方法,那么该派生子类仍然是抽象类,只能用于继承,而不能实例化;
- 抽象类中也可以包含有非抽象的方法,子类中重写非抽象方法时返回值和参数必须与父类一致;
- 构造方法和静态方法不可以修饰为 abstract。
抽象类和接口的比较
参数 | 抽象类 | 接口 |
---|
默认的方式实现 | 可以有默认的方法实现 | 完全抽象,根本不存在方法的实现 | 实现方式 | 子类通过extends去继承,若子类不是抽象类则需要实现父类所有方法,也可以重写 | 子类用implements去实现接口,需要实现所有方法 | 构造器 | 可以有 | 不能有 | 与常规类的区别 | 不能实例化 | 完全不同 | 访问修饰符 | 可以用public,protected,default | 默认是public,不能用别的修饰 | main方法 | 抽象类可以有main | 不能 | 多继承 | 抽象类可以继承一个类和实现多个接口 | 接口只能继承一个或多个接口 | 速度 | 抽象类比接口快 | 接口慢点,因为要去寻找类中实现它的方法 | 添加新方法 | 可以直接添加,若新方法也是抽象,则它的子类也要实现它 | 只能在接口中加 |
重载 与 重写 重载
- 发生同一个类中
- 名字相同
- 参数列表不完全相同
- 返回值相同
- 访问权限修饰符相同
重写
- 发生在父子类中
- 名字相同
- 参数列表相同
- 返回值相同
- 访问权限符不同
|