Java是一门面向对象的编程语言。
语言特点:面向对象,平台无关性,支持多线程,编译与解释并存。
JVM: Java Virtual Machine, Java虚拟机 。
JRE: Java 运行环境。
JDK: Java Development Kit,它是功能齐全的java SDK。(java开发工具包)
JDK包含JRE,JRE包含JVM
编译:将我们的代码(java)编译成虚拟机可以识别理解的字节码(.class)。
解释:虚拟机执行.Java字节码,将字节码翻译成机器能识别的机器码。
执行:对应的机器执行二进制机器码。
源代码:由程序员编写的,使用各种编程语言完成,还没有经过处理的程序文本
编译执行:把源代码每一条指令编译成机器语言,最终生成二进制文件 。精力花费在编译的过程,而一
旦编译完成后,运行的效率很高。 例如C 、C++
解释执行:只有在执行的时候,将源代码一行一行的解释成机器语言。例如 php python
编译型语言是指编译器针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码;解释型语言是指解释器对源程序逐渐解释成特定平台的机器码并立即执行。
Java程序要经过先编译,后解释两个步骤,由java编写的程序需要先经过编译步骤,生成字节码(.*class文件),这种字节码必须再经过JVM,解释成操作系统能识别的机器码,再由操作系统执行。因此,我们可以认为java语言编译与解释并存。
注意:java严格区分大小写。程序中使用的是英文半角符号。
标识符:用来标识类名、对象名、方法名、类型名、数组名、文件名的有效字符序列。
(1)由字母、数字、下划线、美元符号¥(两种均可)组成,并且首字符不能是数字。
(2)不能把java关键字和保留字作为标识符。
(3)标识符对大小写敏感。
(4)标识符无长度限制,但中间不能出现空格。
关键字:Java语言中已经赋予了特定意义的
保留字:Java版本尚未使用,但是以后版本可能会作为关键字使用
变量:程序运行期间可以被改变的量。在程序中使用变量,必须先创建它并为它取一个名字,并且指明它能够存储信息的类型,这称为“变量声明”。也叫容器的创建。
Java 的注释有三种:单行注释、多行注释、文档注释、
重点提示:(有人问为什么long占的字节比float的多还排在float后面?因为在发生转换的时候小数的优先级要大于整数。)不同类型的数据结构先转化为同一类型的,然后再进行计算。
//强制类型转换(一种从低到高,一种从高到低的转换)
低--------------高
byte,short,char->int->long->float->double
数据从低变高
自动转换
数据从高变低
需要强制转换
存在溢出的可能
注意 两个数相加,结果类型
有 long 为 long
有 double 为 double
啥都没有就是 int
分类:算术运算符、赋值运算符、比较运算符、逻辑运算符、三元运算符。
\\选择语句
if()
if() else
if() else if()…… else
switch(表达式){
case (常量):(break;)
}
\\循环语句
for
while
do()while
\\流程跳转语句 break、continue
break:在switch中结束case条件判断,在循环体中结束循环
continue:作用在循环体中,结束循环体的本次循环,而进入下次循环。
import java.util.Scanner
public class Demo{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
Systme.out.println("请输入内容:");
String str = scanner.next();
System.out.printil("输入的内容是:"+str);
}
}
数组是数据的集合,一个容器,用来存储任何类型的数据,包括原始数据类型和引用数据类型,但是一旦指定了数组的类型后,就只能用来存储指定类型的数据。
(1)数据类型【】 数组名 = new 数据类型【长度】
(2)数据类型【】 数组名 = {数据……}
(3)数据类型【】 数组名 = new 数据类型长度【】{数据……}
(1)数据变量的声明
数据类型【】 数组名;如int 【】num;
(2)数组对象的创建
数组名 = new 数据类型【长度】;如 num = new int 【4】;数组声明长度后不可改变
(3)赋值
(4)数组元素的使用及遍历
for(int i = 0; i < arr; i++)
{
System.out.println(""+arr(i));
}
(1)数据变量的声明
数据类型【】【】 数组名;如int 【】【】num;
(2)数组对象的创建
数组名 = new 数据类型【外长度】【内长度】;如 num = new int 【4】【4】;数组声明长度后不可改变
(3)赋值
(4)数组元素的使用及遍历
for(int i = 0; i < arr.length; i++)
{
for(int j = 0; j < arr[i].length;j++){
System.out.println(""+arr[i][j])
}
}
//方法的重载(对于重名的方法利用它对应的参数的不同类型或者参数的个数来进行区分)
1.方法的名称相同
2.访问修饰符可相同可不同
3.返回值类型可相同可不同
4.参数列表必须不同(不区分形参名称的)
(1)参数类型不同
(2)参数个数不同
(3)参数顺序不同(不建议使用)
//可变参数、
JDK1.5开始,指定参数后加一个省略号,一个方法最多一个可变参数,且是最后一个
public class Demo2{
public static void main(String[] args){
Demo2 demo2 = new Demo2();
demow.test(1,2,3,4,5);
}
public void test(int……i){
System.out.println(i[1]);
System.out.println(i[2]);
System.out.println(i[3]);
System.out.println(i[4]);
System.out.println(i[5]);
}
}
//使用var JDK10以后
var a = value;
var会自己判断value的类型,但是必须给var的变量赋值。
对象:客观存在能够相互区分的个体,如汽车、人、房子……。万物皆对象。
类:若干具有相同属性和行为的对象的群体或者抽象,类是创建对象的模板,由属性 和行为两部分组成。
类是对象的概括或者抽象,对象是类的实例化。
类名 变量名 = new 类名
4种访问权限:(低 —> 高)
private,default,protected,public
private:私有访问权限,作用于同一个类
default:默认访问权限,作用于同一个包中的类
protected:受保护的访问权限,作用于不同包的子类
public:公共访问权限,作用于全局范围
概念:将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过提供的方法来实现对隐藏信息的访问和操作。
目的:直接通过操控类的对象来达到目的,不需要对具体实现十分了解,使类属性和方法的具体实现对外不可见。不但方便还起到了保护作用。
//实现封装
class Student{
private String name;
private int age;
//getter和setter方法实现封装
public String getName(){
return name;
};
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
if(age < 0){
System.out.println("您输入的年龄有误!");
}
else{
this.age = age;
}
}
//自己写的阅读程序的方法
public void read(){
System.out.println("名字:"+ name +"年龄:"+ age);
}
}
//主类
public class Demo{
public static void main(String[] args){
Student stu = new Student();
stu.setName("张三");
stu.setAge("18");
stu.read();
}
}
这里的setter和getter是自己写的封装方法,用来实现封装的过程
1.构造方法的名称必须与类名称一致。
2.构造方法的声明处不能有任何返回值类型的声明
3.不能在构造方法中使用return返回一个值。
1.调用本类中的属性,也就是类中的成员变量;
2.调用本类中的其他方法;
3.调用本类中的其他构造方法,调用时要放在构造方法的首行。
//用法1
public class Student{
String name;
private void SetName(string name){
this.name = name;
}
}
//用法2
//this 表示当前对象,this.name是指当前对象具有的变量name,等号右面的name 表示参数传递过来的数值。
public class Teacher{
private String name;
private double salary;
private int age;
}
public Teacher (String name,double salary,int age){
this.name = name;
this.salary = salary;
this.age = age;
}
//注意:当一个类的属性(成员变量)名与访问该属性的方法参数名相同时,则需要使用this关键字来访问类中的属性,以区分属性和方法中的参数。
//用法3
//原来代码内容如下:
public class Dog {
// 定义一个jump()方法
public void jump() {
System.out.println("正在执行jump方法");
}
// 定义一个run()方法,run()方法需要借助jump()方法
public void run() {
Dog d = new Dog();
d.jump();
System.out.println("正在执行 run 方法");
}
}
public class DogTest {
public static void main(String[] args) {
// 创建Dog对象
Dog dog = new Dog();
// 调用Dog对象的run()方法
dog.run();
}
}
//可以用this来实现
public class Dog {
// 定义一个jump()方法
public void jump() {
System.out.println("正在执行jump方法");
}
// 定义一个run()方法,run()方法需要借助jump()方法
public void run() {
// 使用this引用调用run()方法的对象
this.jump();
System.out.println("正在执行run方法");
}
}
//this替代了对象的建立再使用的过程。
代码块是类的成分之一:成语变量,方法,构造器,代码块,内部类。
在java中,使用{ }括起来的代码被称为代码块(Code block)
代码块分类:局部代码块,静态代码块,实例(构造)代码块,同步代码块
局部代码块:用于限定变量生命周期,及早解放,提高内存利用率
静态代码块:主要用于对静态属性进行初始化
实例(构造)代码块:调用构造方法都会执行,并且在构造方法前执行
同步代码块:一种多线程保护机制
public class test1{
public static void main(String[] args){
//局部代码块在代码块外部不能访问
{
int n = 100;
}
}
}
public class Test2 {
public static String name;
// 静态代码块
static {
// 初始化静态资源
name = "张三";
System.out.println("静态代码块执行...");
}
public static void main(String[] args) {
System.out.println("main方法执行...");
System.out.println(name);
}
}
//输出
静态代码块执行...
main方法执行...
张三
特点:
1.每次执行类,加载类的时候都会先执行静态代码块一次
2.静态代码块是自动触发执行的,只要程序启动,静态代码块就会先执行一次
3.在启动程序之前可以做资源的初始化,一般用于初始化静态资源
public class Test3{
private String name;
// 实例代码块。 无static修饰。
{
System.out.println("实例代码块执行...");
name = "张三";
}
// 构造器
public Test3(){
System.out.println("无参构造方法执行...");
}
// 有参数构造器
public Test3(String name){
System.out.println("有参构造方法执行...");
this.name = name;
}
public static void main(String[] args) {
Test3 t1 = new Test3();
Test3 t2 = new Test3("李四");
System.out.println(t1.name + t2.name);
}
}
//输出
实例代码块执行...
无参构造方法执行...
实例代码块执行...
有参构造方法执行...
张三李四
特点:
无static修饰。属于对象,与对象的创建一起执行的。
每次调用构造器初始化对象,实例代码块都要自动触发执行一次。
实例代码块实际上是提取到每一个构造器中去执行的。
实例代码块中的内容在构造方法前执行。
同步代码块指的是被Java中Synchronized关键词修饰的代码块,在Java中,Synchronized关键词不仅仅可以用来修饰代码块,与此同时也可以用来修饰方法,是一种线程同步机制,被Synchronized关键词修饰的代码块会被加上内置锁。
public class Test4 implements Runnable {
@Override
public void run() {
synchronized (CodeBlock.class) {
System.out.print("同步代码块...");
}
}
public static void main(String[] args) {
CodeBlock a = new CodeBlock();
CodeBlock b = new CodeBlock();
new Thread(a).start();
new Thread(b).start();
}
}
可以修饰属性、方法、代码块
继承:泛化,实现子类共享父类属性的方法的机制。在已有类的基础上,扩展出新的类,在新的类中加入特殊的属性和方法。
java 的类是单继承
//语法格式:
class 子类 entends 父类{}
是否可以继承和访问父类私有的属性和方法?
理解一:子类会继承父类的所有属性和方法,是否能访问,是因为访问权限的问题。
java官方文档的解释:子类不能继承父类的私有属性和方法,但是如果子类中公有的方法影响到了父类私有,那私有属性是可以被子类使用的。
总结:父类私有的属性在子类中不可以直接使用,必须通过getter或setter方式进行访问
是否可以继承和访问父类默认的属性和方法?
可以继承,在同包下可以访问,在不同包下不可以访问。
是否可以继承和访问父类受保护的属性和方法?
可以继承,在同包下可以访问,在不同包下也可以访问。
是否可以继承和访问父类公有的属性和方法?
可以继承,在同包下可以访问,在不同包下也可以访问。
总结:私有的不可以访问,默认的在同包下可以访问,受保护的和公有的,可以在不同包访问,相当于在子类中声明一样使用。
子类实例化过程:
父类的构造方法,不能被子继承
在子类的构造方法中,调用了父类的构造方法
如果父类有无参的构造方法,子类super()可以省略
如果父类中没有无参的构造方法,子类super(参数)不可以省略
如果使用super()显式地调用父类的构造方法,要求必须写在子类构造方法中的第一行
子类的构造方法中,不能同时出现 super()和 this()
在子类创建对象时,是否也创建了父类的对象。答:不会创建父类对象。只是创建了父类空间,并进行了初始化操作。
当一个子类继承一个父类的时候,可以重写覆盖原来父类里面的方法,当然这个方法和父类的方法名称一定要相同,参数也相同。
方法重写的要求:(private ,default ,protected ,public)
1、方法名必须相同
2、参数列表必须相同
3、访问修饰符 大于等于父类方法的访问修饰符(访问权限不能比父类中被重写的方法的访问权限更低 例如:如果父类方法被public修饰,则子类中重写该方 法就不能声明为 protected)
4、父类方法不能是私有的(父类被 static, private 修饰的方法、构造方法都不能被重写)
5、返回值类型 小于等于父类方法的返回值类型
重载: “两同一不同” ,同一个类,相同的方法名,参数列表不同。
重写:继承以后,子类覆盖父类中同名同参数的方法。
抽象方法:使用 abstract 关键字修饰,只有方法的声明(方法头),没有方法的实现(方法体)。不是静态方法(static)【没有方法体的方法】
抽象类:使用 abstract 关键字修饰,可以有抽象方法,也可以有普通方法,也可以有构造方法,也可以没有抽象方法。如果一个类中有抽象方法,则这个类必须是抽象类。抽象类不能实例化。【包含抽象方法的类】
方法重写的时候,必须要重写的方法是 abstract 修饰的抽象方法。如果子类不重写父类的抽象方法,子类必须是抽象类。
//定义方法:
修饰符 abstract 返回值类型 方法名(参数列表);
eg: public abstract void run();
如果一个类包含抽象方法,那么这个类一定是抽象类
抽象类不一定有抽象方法,但是有抽象方法的类一定是抽象类
抽象类可以写抽象方法,但是不能创建对象
class Person{
public String info = "TGU";
}
class Student extends Person{
public String info = "CSC";
public void print(){
System.out.println("父类中的属性:" + super.info);
System.out.println("子类中的属性:" + this.info);
}
}
public class Demo{
public static void main(String[] args){
new Student().print();
}
}
接口中没有成员变量,只有公有静态常量(public static final)
默认情况下接口变量:public static final 数据类型 常量名 = 常量值
概念:Java接口就是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)
(JDK1.8以前:接口是解决 Java 无法使用多继承的一种手段,但是接口在实际中更多的作用是制定标准的。或者接口理解成100%的抽象类,既接口中的方法必须全部是抽象方法)
就像一个类一样,一个接口也能够拥有方法和属性,但是在接口中声明的方法默认是抽象的。(即只有方法标识符,而没有方法体)。
接口指明了一个类必须要做什么和不能做什么,相当于类的蓝图。
一个接口就是描述一种能力,比如“运动员”也可以作为一个接口,并且任何实现“运动员”接口的类都必须有能力实现奔跑这个动作(或者implement move()方法),所以接口的作用就是告诉类,你要实现我这种接口代表的功能,你就必须实现某些方法,我才能承认你确实拥有该接口代表的某种能力。
如果一个类实现了一个接口中要求的所有的方法,然而没有提供方法体而仅仅只有方法标识,那么这个类一定是一个抽象类。(必须记住:抽象方法只能存在于抽象类或者接口中,但抽象类中却能存在非抽象方法,即有方法体的方法。接口是百分之百的抽象类)
一个JAVA库中接口的例子是:Comparator 接口,这个接口代表了“能够进行比较”这种能力,任何类只要实现了这个Comparator接口的话,这个类也具备了“比较”这种能力,那么就可以用来进行排序操作了。
接口被用来描述一种现象
Java不像 C++ 一样支持多继承,所以 Java 可以通过实现接口来弥补这个局限。
接口也被用来实现解耦
接口被用来实现抽象,而抽象类也被用来实现抽象,为什么要用接口?接口和抽象类之间区别是什么呢? ( 抽象类内部可能包含非 final 的变量,但是在接口中存在的变量一定是final )
interface exam1{
final int a = 10;
void display();
}
//必须实现接口的所有功能才能使用接口
class test implements exam1{
public void display(){
System.out.println("Geek");
}
}
接口的定义:[访问修饰符] interface 接口名{}
接口中的数据成员,全部是公有的静态常量
类和接口的关系 :class 类名 implements 接口名
在jdk1.8之前,接口中的方法,全部是公有的抽象方法
接口不是类,没有构造方法,不能实例化
接口可以实现多继承
一个接口,可以被多个类实现
一个类可以实现多个接口: class 类名 implements 接口1[,接口2...]{}
一个类可以在继承一个父类的同时,实现一个或多个接口: class 类名 extends 父类 implements接口1[,接口2...]{}
final关键字不能和abstract关键字放在一起使用。
final定义常量:
修饰引用类型: 无法更改引用所指向的对象地址。引用的对象属性可以修改。修饰基本数据类型:值不能被修改
编译期常量、非编译期常量
不是所有的final修饰的字段都是编译期常量,非编译期常量,在被初始化之后无法修改
static final:
一个既是static,又是final的字段,只占据一段不能改变的存储空间。
final定义终结类:
当一个类定义为final 时,就表明不能继承这个类,表示不能产生子类。
final类里面的所有方法,都是隐式的final,不会产生子类,也不会覆盖方法,所以不需要在final类中
为方法加final关键字。
final定义终结方法:
不能被子类重写。所有private方法都是隐式地final方法,在private方法中,不需要使用final关键
字修饰。
final方法可以被重载。
更多内容请前往下一章:Java基础学习(进阶版)-CSDN博客
public final void test(){
}
public final void test(int x){
}