一、Java概述
1、Java语言介绍2、Java语言特点3、Java和C++区别4、Java版本5、JDK、JRE和JVM6、字节码7、Oracle JDK 和 OpenJDK 的对比8、Java开发环境配置 二、基础语法
1、关键字、保留字、标识符2、注释3、数据类型及转换4、访问权限修饰符5、运算符6、一维数组7、关键字
(1)final关键字(2)this关键字(3)super关键字(4)static关键字
①静态变量②静态方法③静态代码块、构造代码块 8、流程控制语句9、main函数 三、面向对象
1、三大特征
特征1:封装特征2:继承特征3:多态 2、类与对象3、变量区别4、方法覆盖(复写,重写)override、方法重载overload5、构造器(构造函数、构造方法)6、抽象类abstract7、接口interface
接口和抽象类区别
一、Java概述 1、Java语言介绍
2、Java语言特点
(1)面向对象
(2)简单好用
Java语言由C和C++演变而来,它省略了C语言中所有的难以理解、容易混淆的特性(比如指针),更加严谨、简洁、易使用。
(3)健壮性
具有安全检查机制,还具备了许多保证程序稳定、健壮的特性(强类型机制、异常处理、垃圾的自动收集等),有效地减少了错误,使得Java应用程序更加健壮。
(4)安全性
Java通常被用在网络环境中,为此,Java提供了一个安全机制以防恶意代码的攻击,从而可以提高系统的安全性。
(5)平台无关性(跨平台性)
java语言编写的程序,一次编译后,可以在多个系统平台上运行。(不受计算机硬件和操作系统的约束)
Java平台无关性由Java 虚拟机(JVM Java Virtual Machine)实现。
(6)支持多线程
C++ 语言没有内置的多线程机制,必须调用操作系统的多线程功能来进行多线程程序设计。
而 Java 语言却提供了多线程支持。
多线程机制使应用程序在同一时间并行执行多项任务,
该机制使得程序能够具有更好的交互性、实时性。
(7)分布式(支持网络编程)
Java语言具有强大的、易于使用的网络能力,非常适合开发分布式计算的程序。
java中提供了网络应用编程接口(java.net),使得我们可以通过URL、Socket等远程访问对象。
(8)编译与解释共存
都是面向对象的语言,都支持封装、继承和多态Java不提供指针来直接访问内存,程序内存更加安全Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。Java有自动内存管理机制,不需要程序员手动释放无用内存
4、Java版本
JAVASE:Java Platform Standard Edition,标准版,完成 桌面应用程序 的开发,是其它两者的基础;
JAVAME:Java Platform Micro Edition,小型版,开发 电子消费产品和嵌入式设备,如手机中的应用程序;
JAVAEE:Java Platform Enterprise Edition,企业版,开发 企业环境下的应用程序,主要针对web应用程序开发;
1,JDK:Java Development Kit,java的开发和运行环境,java的开发工具和JRE。
2,JRE:Java Runtime Environment,java程序的运行环境,java运行的所需的类库+JVM。
核心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包。
3、JVM:Java Virtual Machine,java虚拟机,用于保证java的跨平台的特性。
java语言是跨平台,jvm不是跨平台的。
Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟机器。
这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。
编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由 解释器 来将虚拟机代码转换为特定系统的机器码执行。
在Java中,这种供虚拟机理解的代码叫做字节码(即Java源代码经过虚拟机编译器编译后产生的文件,扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机,使Java程序无须重新编译便可在多种不同的计算机上运行。
每一种平台的解释器是不同的,但是实现的虚拟机是相同的。
一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点,使Java程序运行时比较高效。
Java源代码---->编译器---->jvm可执行的Java字节码(即虚拟指令)---->jvm(字节码由虚拟机解释执行)---->jvm中解释器(虚拟机将每一条要执行的字节码送给解释器)----->机器可执行的二进制机器码---->程序运行。
javac:负责的是编译的部分,当执行javac时,会启动java的编译器程序,对指定扩展名的.java文件进行编译,生成jvm可以识别的字节码文件,即class文件,java的运行程序。
java:负责运行的部分,会启动jvm,加载运行时所需的类库,并对class文件进行执行。
Oracle JDK版本将每三年发布一次,OpenJDK版本每三个月发布一次;
OpenJDK 是一个参考模型并且完全开源,Oracle JDK是OpenJDK的一个实现,不是完全开源的;
Oracle JDK 比 OpenJDK 更稳定,具有更好的性能。
OpenJDK和Oracle JDK的代码几乎相同,但Oracle JDK有更多的类和一些错误修复。
Oracle JDK不会为即将发布的版本提供长期支持,用户每次都必须通过更新到最新版本获得支持来获取最新版本;
8、Java开发环境配置(1)path环境变量的配置:
path是配置Windows可执行文件的搜索路径,即扩展名为.exe的程序文件所在的目录,
用于指定DOS窗口命令的路径。
告诉操作系统到哪里去找javac可执行程序配置。
永久配置方式:
JAVA_HOME=%安装路径%Javajdk
path=%JAVA_HOME%bin
临时配置方式:
set path=路径;
(2)classpath的配置:
Classpath是配置class文件所在的目录,用于指定类搜索路径,JVM就是通过它来寻找该类的class类文件的。
给jvm用,告诉jvm到哪里加载字节码文件配置。
如果没有定义环境变量classpath,java启动jvm后,会在当前目录下查找要运行的类文件;
如果指定了classpath,那么会在指定的目录下查找要运行的类文件。
二、基础语法 1、关键字、保留字、标识符
(1)关键字:被赋予特殊含义的词
(2)保留字:尚未使用,但以后版本可能会作为关键字使用的词,const、goto。
(3)标识符:自定义的词。如类名、变量名、函数名、文件名等
由字母、数字、下划线“_”、美元符号“$”或者“¥”组成,首字符不能是数字。
大小写敏感。
单行注释
格式:// 注释文字
多行注释
格式:
文档注释
格式:
可用来生成网页格式的帮助文档。
多行和文档注释都不能嵌套使用。
(1)数据类型
①基本数据类型(原始数据类型)(4类8种):
整数类型:byte、short、int、long
浮点数类型:float、double
字符类型:char
布尔类型:boolean
②引用数据类型:
类、接口、数组
(2)类型转换
精度从高到低 double float long int short(char) byte
自动类型转换(隐式转换):低精度–>高精度
强制类型转换(显示转换): 高精度–>低精度(精度会下降)
5、运算符
(1)逻辑运算符
用于连接boolean类型表达式。
&:逻辑与,只有两边都为true结果是true。否则就是false。(无论左边结果是什么,右边都参与运算)
&&:短路与,如果左边为false,那么右边不参数与运算。
|:逻辑或,只要两边都为false结果是false,否则就是true。(两边都参与运算)
||:短路或,如果左边为true,那么右边不参与运算。
^:异或:两边结果一样,为false,不一样,为true。
(2)位运算符
用于操作二进制位的运算符。
& | ^ << >> >>>(无符号右移)
举例:
交换变量存储的数据,不使用第三个变量
法一:
a = a + b; b = a - b; a = a - b;
法二:
a = a ^ b;b = a ^ b;//b = a ^ b ^ b = aa = a ^ b;//a = a ^ b ^ a = b;
(3)short s1 = 1; s1 = s1 + 1;(x)与short s1 = 1; s1 += 1;(√)
对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int型,需要强制转换类型才能赋值给 short 型。
而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其中有隐含的强制类型转换。
数据类型 [ ] 数组名 = new 数据类型 [ 长度 ] ;
数据类型 [ ] 数组名 = { 数据,数据,…,数据 } ;
数据类型 [ ] 数组名 = new 数据类型长度 [ ] { 数据,数据,…,数据 };
二维数组同理。
①修饰类
称为最终类。
不可被继承,final 类中的所有成员方法都会被隐式的指定为 final 方法,
②修饰方法
称为最终方法,不可被覆盖
③修饰变量
称为常量,只能赋值一次.
如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;
如果是引用类型的变量,则在对其初始化之后便不能让其指向另一个对象,但是可以改变引用指向的内容。
内部类只能访问被final修饰的局部变量。
(2)this关键字
本质上是一个指向本对象的指针。
不可以在static环境中使用。包括:static变量,static方法,static代码块。
this关键字的用法:
①super.属性名、super.方法名();
表示本类类型的对象引用.
用于区分同名成员变量和局部变量 或者 在定义函数时,该函数内部要用到调用该函数的对象时,但此时对象还没建立,用this代表此对象。
②super([参数列表])
注意:用this调用构造函数,必须定义在构造函数的第一行。
public class TestThis{int i = 2;public TestThis(){System.out.println("这是无参构造方法");}public TestThis(int i){this();//通过this()调用无参构造方法。this.i = i;}public void test(){int i = 3;//局部变量与成员变量同名,成员变量将被隐藏System.out.println(i);//通过this.成员变量名 访问被隐藏的成员变量System.out.println(this.i);}}
(3)super关键字
super()和this()不可以同时出现的构造函数中。
是指向直接(离自己最近的一个)超(父)类对象的指针。
不可以在static环境中使用。包括:static变量,static方法,static代码块。
super关键字的用法:
①super.属性名、super.方法名();
表示指向当前对象的父类的引用。
用于区分同名子类成员和父类成员,用super。
②super([参数列表])
调用的是父类中的对应参数的构造函数。
注意:用super调用构造函数,必须定义在构造函数的第一行。
(4)static关键字 ①静态变量
修饰成员变量。
特点:
1)随着类的加载而加载。
2)优先于对象存在。
3)对所有对象共享,在内存中只有一个副本。
4)可以被类名直接调用。
5)初始化顺序按照定义的顺序进行。
调用格式:类名.静态变量名
②静态方法
修饰成员方法。
特点:只能访问静态成员,不可以访问非静态成员。
原因:静态内容是随着类的加载而加载,先进内存。
非静态成员必须依赖具体的对象才能被调用。
用法:当某个方法没有访问该类中的非静态成员,就可以把这个方法定义为静态修饰。
调用格式:类名.静态方法名()
③静态代码块、构造代码块
静态代码块:
定义在类中, 可以完成类的初始化(如初始化一些静态变量)。
随着类的加载而执行,只执行一次,因此可以用来优化程序性能。
常将只需要进行一次的初始化操作都放在static代码块中进行。
如果和主函数在同一类中,则优于主函数执行。
一个类中可以有许多静态初始化块,并且可以出现在类体的任何地方。
运行时系统会保证静态初始化块会按照它们在源代码中出现的顺序被调用
构造代码块:
给所有的对象进行初始化,也就是说,所有的对象都会调用一个代码块,只要对象一建立,就会调用。
静态代码块、构造代码块、构造函数同时存在时的执行顺序:
静态代码块 -->构造代码块 --> 构造函数
跳出多重嵌套循环:
在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break 语句,即可跳出外层循环。
举例:
public static void main(String[] args) { flag: for (int i = 0; i < 10; i++) for (int j = 0; j < 10; j++) { System.out.println("i=" + i + ",j=" + j); if (j == 5) break flag; }}
9、main函数
main函数是静态的
public static void main(String[] args)
static:jvm调用main方法的时候,没有创建对象。只能通过类名调用,故main必须用static修饰。
void:main方法是被jvm调用,不需要返回值,故用void修饰。
main:主要,程序入口。
在运行的时候,通过java命令给args数组赋值。
格式:java MainTest hello world itcast
隐藏对象的属性和实现细节,仅对外提供公共访问方式。
将变化隔离;方便使用;提高复用性;提高安全性
用extends关键字表示
多个具体的对象,不断的向上抽取共享的内容,最终形成了一个体系。这个体系叫做继承体系。
java不支持多继承(一个类同时继承多个父类),但支持多重继承(A继承B B继承C C继承D)
一个对象在程序不同运行时刻代表的多种状态,父类或者接口的引用指向子类对象。
通过多态可以提高代码的可重用性,降低模块之间的耦合度。
(1)Java实现多态的两种形式
①继承
多个子类对同一方法的重写。
继承是多态的前提。
②接口
实现接口并覆盖接口中同一方法。
(2)Java实现多态的三个必要条件:继承、重写、向上转型。
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能有 调用父类的方法和子类的方法 的能力。
当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
2、类与对象
类变量的声明:类名 对象名;
如:Student stu;
类对象的创建,赋值给变量:对象名 = new 构造器([参数列表]);
如:stu = new Student();
类是创建对象的模板,由属性和行为两部分组成。
类是对象的概括或者抽象,对象是类的实例化。
成员变量(实例变量):对应事物的属性(成员函数对应事物的行为)。
匿名对象:应用于只调用一次类中的方法或作为实际参数在方法传递中使用
(1) 在子类方法中使用一个变量
首先,在方法的局部变量中找这个变量,有则使用。
否则,在本类中找成员变量,有则使用。
否则,在父类中找成员变量,有则使用。
否则,报错。
如果想要调用父类中的属性值,需要使用一个关键字:super(子类所属的父类中的内存空间引用)
(2)在子类对象使用一个方法
首先,在子类中找这个方法,有则使用。
否则,在父类中找这个方法,有则使用。
否则,报错。
(3)对象的加载过程:
加载父类,为父类静态变量分配内存
加载子类,为子类静态变量分配内存
执行父类静态变量的赋值运算,和静态初始化块
执行子类静态变量的赋值运算,和静态初始化块
(4)子类的实例化过程
① 子类创建对象时,会先去创建父类的对象,为父类实例变量分配内存
② 新建子类实例,为子类实例变量分配内存
③ 执行父类的实例变量赋值运算
④ 执行父类的构造方法
⑤ 执行子类的实例变量赋值运算
⑥ 执行子类的构造方法
子类构造函数运行时,先运行父类的构造函数。
因为子类的所有构造函数中的第一行有一条隐身的语句super();(调用父类中空参数的构造函数)
如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过super语句指定要访问的父类中的构造函数。
Person p = new Person();在内存中做了哪些事?
① 将Person.class文件加载进内存中。
② 如果p定义在主方法中,那么,就会在栈空间开辟一个变量空间p。
③ 在堆内存给对象分配空间。
④ 对对象中的成员进行默认初始化。
⑤ 对对象中的成员进行显示初始化。
⑥ 调用构造代码块对对象进行初始化。(如果没有就不执行)
⑦ 调用构造方法对对象进行初始化。对象初始化完毕。
⑧ 将对象的内存地址赋值给p变量,让p变量指向该对象。
3、变量区别
变量:程序运行期间可以被改变的量。
在程序中使用变量,必须先创建它并为它取一个名字,并且指明它能够存储信息的类型,称为“变量声明”,也叫容器的创建。
4、方法覆盖(复写,重写)override、方法重载overload
方法重载overload:
函数名相同、参数个数或者参数类型不同
实现的是编译时的多态性(也称为前绑定)
5、构造器(构造函数、构造方法)方法重写(override):
实现的是运行时的多态性(也称为后绑定)。
子类从父类继承的某个实例方法无法满足子类的功能需要时,需要在子类中对该实例方法进行重新实现。
在不同类中(子父类中),方法声明相同(返回类型,方法名,参数列表均相同)。
要求:子类方法的访问权限要大于等于父类方法的访问权限,并且静态只能重写静态。
作用:给对应的对象初始化。
所有对象创立时,只有初始化才可以使用。(有默认无参构造函数)
特点:
1)函数名与对应的类名相同
2)无返回值,但不能用void声明构造函数
3)生成类的对象时自动执行,无需调用
6、抽象类abstract定义一个无参空函数体的构造器的作用:
Java程序在执行子类的构造方法之前,如果没有显式的用super()调用父类特定的构造方法,则会直接调用父类中没有参数的构造方法。
因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,
因为Java程序在父类中找不到没有参数的构造方法可供执行。
解决办法是在父类里加上一个不做事且没有参数的构造方法。
抽象类的声明:[修饰符] abstract class 类名 [extends 父类名]{类体}
抽象方法的声明:[修饰符] abstract 返回值类型 方法名([参数列表]);
抽象方法无法确定具体执行功能,没有方法体,需要在小括号后加上分号。
所有的对象都是通过类来描述的,但不是所有的类都用来描述对象。
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。
抽象方法仅为了不让该类创建对象。只能定义在抽象类中,并且只定义方法声明,不定义方法实现,不可以被创建对象(实例化对象)。
只有通过子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化(抽象类只有被继承才可使用)。否则,该子类还是一个抽象类。
当有一部分内容是不想让子类修改的,但是子类又都通用,同时各自又有其特点,那么就适合使用抽象类。
抽象类可以定义实例变量和静态变量以及常量
抽象类可以再继承抽象类,也可以继承普通的类
用interface关键字表示。类与接口关系用implements表示。
(Implements代替extends,Interface 代替class)
接口的声明:[修饰符] interface 接口名{[常量];[抽象方法];}
接口的实现:
[修饰符] class 类名 [extends 父类名] [implements 接口1,接口2,……]{类体部分}
接口的特点:
1)接口只能定义抽象方法
2)接口只能定义常量
3)接口只能继承接口,不能继承普通的类和抽象类
4)接口没有构造方法
接口的作用:
1)提高程序的重用性
2)提高程序的可扩展性
3)降低程序的耦合度
4)实现了多继承
注意:
1)在接口中定义常量时,可以不用final static修饰,因为编译器在编译时会自动加上。
2)在接口中定义抽象方法时可以省略abstract关键字,编译器在编译时同样会加上。
(接口中的成员只能是常量和抽象方法。)