Java基础
第一个hello world
1 | public class Hello { |
在java中 public class Hello {...}
,这样的定义被称为类class,类名为Hello
花括号里面则是类的定义。
里面第二行则有一个main
方法,方法里面是参数,参数名是args。类型是String[]
前面则是修饰方法。这里的public static void main(String[] args)
是Java程序的固定入口方法,因此,Java程序总是从main
方法开始执行就相当于c语言的main()方法一样。
最后的System.out.println("Hello, world!");
则是打印hello,world
文件保存的时候,要保证类名和文件名相同,比如这个文件就应该叫Hello.java
否则就无法运行。
基础
简单讲解
1 | public class TuNan { // 类名是TuNan |
在java中类是程序的基本单位 class
是关键字,TuNan是类名,public
是访问修饰符,表公开,不写可以正常编译,但是无法在命令行运行。
- 类名必须以英文字母开头,后接字母,数字和下划线的组合
- 习惯以大写字母开头(大驼峰命名)
在class内可以定义许多方法
1 | public class TuNan { |
在这里方法名为main
返回值是void
即为空,public和static
修饰方法static
表示静态方法,java入口程序只能是这样写。
- 方法名必须以英文字母开头,后接字母,数字和下划线的组合,和类名一样
- 习惯小写字母开头(小驼峰命名)
方法的三种调用方式
- 单独调用:方法名称(参数);
- 打印调用:System.out.println(方法名称(参数));
- 赋值调用:res = 方法名称(参数);
方法的注意事项
- 方法应该定义在类当中,不能在方法中再定义方法。
- 方法定义的前后顺序无所谓。
- 方法定义后并不会执行,如果想要执行的话,就一定要进行调用。
- 如果方法有返回值,则需要使用
return
返回。 - 返回值类型一定要与定义方法时的返回值类型一致。
- 一个方法中可以有多个return语句,但是只有一个可以被执行到,执行的同时,退出方法
方法的重载
对于功能类似的方法,如果每一次都使用一个新的名称写的话,就会使代码比较乱,所以可以使用方法的重载。
方法的重载:方法名称相同,参数列表不同。
1 | public class Learn { |
方法重载与下列因素相关:
- 参数个数不同
- 参数类型不同
- 参数多类型顺序不同
方法重载与下列因素无关:
- 与参数名称无关
- 与方法的返回值类型无关
字符串还要一个重写,在下面讲了继承的时候在说。
java有三种注释
1 | // 单行注释 |
demo
1 | public class Learn { |
字符与字符串
字符
字符类型char
表示一个字符。字符类型使用'
,只有一个字符与"
的字符串类型分开。
java的基本数据类型
- 整数类型:byte,short,int,long
- 浮点数类型:float,double
- 字符类型:char
- 布尔类型:boolean
字符串
字符串是引用类型,使用"..."
表示字符串。一个字符串可以存储0到任意长度的字符。
字符串是不可变的。
1 | public class Learn { |
当String a= "hello"
时,JVM开辟一个内存,写入hello,然后让a指向hello
,当重新赋值a=tunan
并不是原有内存里的hello
被tunan
覆盖了,而是重新在开辟一个内存空间,写入tunan
,然后修改a,让他指向这个内存。所以字符串的不可变是指字符串内容不可变。
字符串的三种构造方法
- public String():创建一个空白字符串,不含有任何内容。
- public String(char[] array):根据字符数组的内容,来创建对应的字符串。
- public String(byte[] array):根据字节数组的内容,来创建对应的字符串。
1 | //字符串的三种构造方法 |
常用的字符串操作
- 获取字符串长度 public int length()
- 拼接字符串 public String concat(String str)
- 查找字符串中某字符首次出现位置 public int indexOf(String str)
- 截取字符串 public String subString(int index)
- 把字符串中特定字符全部转换为新的字符 public String replace(CharSequence oldString, CharSequence newString)
- 将字符串拆分成为字符数组 public char[] toCharArray()
- 获取字符串底层字节数组 public byte[] getBytes()
1 | public static void commanStrMethod() { |
- 字符串分割 public String[] split(String regex) 这个里面的参数其实是正则表达式, 需要按照特定的规则选择特定参数。
1 | public static void cutStr() { |
数组
- 数组与上面的字符串一样为引用类型
- 数组长度在运行中不可变
- 数组中数据类型必须统一
数组有两种创建类型
- 动态初始化(指定长度)
- 静态初始化(指定内容)
如果不确定数组当中的具体内容,则使用动态初始化,否侧,已经确定了具体的内容,则使用静态初始化。
1 | 数据类型[] 数组名称 = new 数据类型[数组长度]; |
获取数组长度也是通过 public int length()
数组有两种遍历方法,一种是for
循环,通过索引遍历数组 另一种是for each
循环,直接迭代数组的每个元素(for each 直接获取数组元素,无法得到索引。)
1 | public static void traverseArray(){ |
面向对象
编程思想分两种一种是面向过程,一种是面向对象。
面向过程:为了实现一个功能,分析需要的步骤,然后用函数一一实现,使用时在一一调用即可。
面向对象:把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
类
通常情况下,类不能直接使用,需要根据类创建一个对象才能使用。
- 创建类
类名称 对象名 = new 类名()
- 使用
- 使用成员变量:对象名.成员变量名
- 使用成员方法:对象名.成员方法名(参数)
- 导包(import 包名称.类名称):就是指出所使用的类在什么位置。对于和当前类属于同一个包的情况,可以省略包名称不写。
1 | //Learn类 |
this关键字
当方法的局部变量和类的成员变量重名的时候,根据“就近原则”,优先使用局部变量。如果需要访问本类中的成员变量,需要使用this.成员变量名
这种格式
对象与方法
对象作为参数与返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51//man.java
package man;
public class Man {
private String name = "TuNan";
private int age = 18;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//Learn.java
import man.Man;
public class Learn {
public static void main(String[] args) {
Man human = new Man();
human.setAge(21);
human.setName("tunan");
var a = echoStr(human);
System.out.println("-----------------------------");
System.out.println(a.getName());
System.out.println(a.getAge());
}
public static Man echoStr(Man human) {
System.out.println(human.getAge());
System.out.println(human.getName());
System.out.println(human);
Man student = new Man();
student.setAge(15);
student.setName("A");
return student;
}
}可以看到,对象作为方法的返回值,返回的是对象的地址值。
封装
上面看到我使用了private
修饰了变量,使用了private
修饰的变量只能在本类之中访问,要想在其他地方访问就需要使用Getter
和Setter
方法。
- 使用
Setter
方法,方法名称必须是’set变量名()’,其中变量名首字母大写 - 返回值必须是
void
- 只能在本类中访问,即
Man
类中,在Learn
类中无法直接访问,但是可以通过Setter
方法间接设置其值。
Getter
方法
- 必须有返回值,返回值类型与被修饰的成员变量类型相同
- 其余与
Setter
基本差不多。
构造方法
格式:
1 | public 类名称 (参数类型 参数名称) { |
构造方法是专门用来创建对象的方法。
- 构造方法的名称必须和所在的类名称完全一样。
- 构造方法不要写返回值类型,包括void。
- 构造方法不能return一个返回值。
- 如果没有编写任何构造方法,那么编译器会自动写一个构造方法,然后什么事情都不做。
- 构造方法也是可以重载的。
构造方法常常用来初始化类中的成员变量。
Scanner类
Scanner类是用来交互的类,可以读取键盘输入。
1 | import java.util.Scanner; |
继承
继承就是子类继承父类的特征和行为,使得子类对象具有父类的实例域和方法
1 | class 父类 { |
- 父类也可称作基类和超类。
- 子类也可叫派生类
方法的重写(覆盖)
在继承中,方法的名称一样,参数也一样
注意事项
- 子类与父类的名称参数要一致
- 子类方法的返回值必须小于等于父类方法的返回值范围。
- 子类方法的权限必须大于等于父类方法权限修饰符
super方法
- 在子类的成员方法中,访问父类的成员变量。
- 在子类的成员方法中,访问父类的成员方法。
- 在子类的构造方法中,访问父类的构造方法
this方法
由于this的就近原则,那么在那个类就会优先使用那个类的方法,变量等。
继承的特点。
Java语言是单继承的,也就是说,一个类的直接父类只能有唯一一个。
java支持多重继承,即a继承b,b继承c
1 | //多重继承 |
抽象
如果父类当中的方法不确定如何进行,那么这种方法就是一个抽象方法。
比方说,对于正方形,三角形,圆形三种类,他们每种图形都有属于自己的计算面积的方法,但是他们都继承自图形类,现在让要求写一个“计算图形面积”的方法,这样的方法是不确定如何实现的,这样的方法就被叫做抽象方法。
格式
- 抽象方法:在方法前加上abstract关键字,然后去掉大括号,直接分号结束。
- 抽象类:抽象方法所在的类必须是抽象类,在class前加上abstract关键字即可。
1 | public abstract class Graph { |
demo
1 | public class Main { |
注意事项
- 抽象类不能直接创建对象,如果创建则无法通过编译而报错,只能创建其非抽象子类的对象。
- 抽象类中可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
- 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类。
- 抽象类的子类必须要覆盖抽象父类中所有的抽象方法,否则会报错,除非该子类也是抽象类
接口
接口是一个抽象类型,是抽象方法的集合,用interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
1 | public interface 接口名称 { |
当一个具体的class去实现interface
时,需要使用implements
关键字。
1 | public class 类名 implements 接口名 { |
接口的实现类必须覆盖重写接口中所有的抽象方法。如果实现类并没有覆盖重写接口的所有抽象方法,那么这个实现类自己必须是抽象类
接口也可以相互继承
一个interface
可以继承自另一个interface
。interface
继承自interface
使用extends
,它相当于扩展了接口的方法。
1 | interface People { |
类可以实现多个接口。
1 | public class 类名 implements interfaceA,interfaceB { |
从java 8开始,接口里允许定义默认方法
1 | public default 返回值类型 方法名称(参数列表) { |
实现类可以不必覆写default
方法。default
方法的目的是,当我们需要给接口新增一个方法时,会涉及到修改全部子类。如果新增的是default
方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法
接口静态成员变量
因为interface
是一个纯抽象类,所以它不能定义实例字段。但是,interface
是可以有静态字段的,并且静态字段必须为final
类型
1 | public interface Person { |
参考