文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、初始java
1.1 java的由来
Java是由Sun Microsystems公司于1995年5月推出的Java程序设计语言(以下简称Java语言)和Java平台的总称。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台.Java平台由Java虚拟机(Java Virtual Machine)和Java 应用编程接口(Application Programming Interface、简称API)构成。Java分为三个体系J2SE(Java2 Standard Edition),J2EE(Java 2 Platform,Enterprise Edition),J2ME(Java 2 Micro Edition)。
它是个面向网络的程序设计语言,用来让程序员创建应用程序,这些应用程序可以通过网络下载,而且可在任何计算平台上安全地运行。如果再加上万维网和公司内部网体系,你将会拥有一个标准的网络计算环境,Java作为一个分布式的,面向对象的程序设计语言,可以让位于任何地方的任何计算机应用网络上的应用程序。
--------------参考链接--------------
1.2 jdk的安装
--------------参考链接--------------
1.3 main方法
public static void main(String[] args) { };
- public:main方法启动时由JVM进行加载,public的可访问权限是最高的,所以声明为public
- static:方法的调用可以通过对象和类,而main方法是由虚拟机调用的,无需生成对象,所以声明为static
- void:main方法退出时,没有需求有相关返回值返回,所以为void;
- main:方法名为main
- String[]:该字符串数组用来运行时接收用户输入的参数
--------------参考链接--------------
二、数据类型与变量
2.1 基本数据类型
常用的八种基本数据类型:
- byte 字节类型; 占1个字节
- short 短整型; 占2个字节
- int 整型; 占4个字节
- long 长整型; 占8个字节
- float 浮点类型; 占4个字节
- double 双精度浮点类型; 占8个字节
- char 字符类型; 占2个字节
- boolean 布尔类型; 占1个字节
这八种基本类型都有对应的包装类分别为: Byte 、 Short 、 Integer 、 Long 、 Float 、 Double 、Character 、 Boolean
注意:Java 里使用 long 类型的数据一定要在数值后面加上 L ,否则将作为整型解析。
--------------参考链接--------------
2.2 引用数据类型
常见的五种引用数据类型:
- 数组
- 类
- 接口
- 抽象类
- 自定义类型:Person
三、运算符
-
int a = 100; System.out.println(3<a<100);
java中这种运算符的使用是一种错误语法。
-
逻辑与
布尔表达式1 && 布尔表达式2
如果表达式1为真,那么就去执行表达式2,如果表达式2也为真,那么整体为真;如果表达式1为假,那么就不会执行表达式2。
3.逻辑或
布尔表达式1 || 布尔表达式2
如果表达式1为真,就不执行表达式2,整体已经为真,就已经发生短路了;
如果表达式1为假,就继续执行表达式2,表达式2为真,那么整体为真。
此表达式为真,至少要一个表达式为真。
4.逻辑非
!布尔表达式
!true ----> false;
!false ----> true.
5.按位与 &
0000 1011
0000 0111
----------
0000 0011
对应位只要有0,就是0。
6.按位或 |
1011
0001
-----
1011
对应位只要有1,就是1。
7.按位异或 ^
0010 1011
0001 1010
----------
0011 0001
对应位不一样就是1,一样就是0。
8.移位
左移:
0000 1011 << 1 ---->0001 0110
在右边补0
右移:
0000 1011 >> 1 ----> 0000 0101
右移是补符号位
无符号右移 >>> :通通在左边补0;
注意:java中没有无符号左移。
四、程序逻辑控制
4.1 if 分支结构
if 分支结构主要是针对于关系表达式进行判断处理的分支操作。对于分支语句主要有三类的使用形式,使用的关键字:if、else if、else。
4.2 switch 分支结构
switch 是一个开关语句,它主要是根据内容来进行的判断,需要注意的是 switch 中可以判断的只能够是数据(int、char、枚举、String),而不能使用逻辑判断。
int num=2;
switch (num) {
case 2:
System.out.println("2");
break;
case 1:
System.out.println("1");
break;
default:
System.out.println("0");
break;
}
4.3 while 循环结构
while循环结构包含while循环和do…while循环。
while循环:
int sum = 0;// 保存最终的计算总和
int num = 1;//进行循环控制
while (num <= 100) { //循环的执行条件
sum += num; //累加
num++; //修改循环条件
}
do…while循环:
int sum = 0;// 保存最终的计算总和
int num = 1;//进行循环控制
do { //循环的执行条件
sum += num; //累加
num++; //修改循环条件
} while (num <= 100);
while 循环是先判断后执行,而 do…while先执行一次后判断。
4.4 for 循环结构
int sum = 0;// 保存最终的计算总和
for (int i = 0; i <= 100; i++) {
sum += i; //累加
}
对于 while 和 for 循环的选择只有一个参考标准:
-
在明确确定循环次数的情况下优先选择 for 循环;
-
在不知道循环次数但是直到循环结束条件的情况下使用 while 循环;
4.5 循环控制
在循环语句定义的时候还有两个控制语句:break、continue。
break是结束所有循环,continue是结束本次循环。
五、方法的使用
5.1 方法的定义
Java当中把函数叫做方法,是用于完成某个功能,模块化的组织代码。
5.2 方法的重载
对于方法的重载,方法名一定要相同,参数列表不相同(顺序,数据类型,个数),对于返回值不做要求。
同一个类中方法的重载:
public class Main {
public static int sum(int x,int y) {
return x+y;
}
public static double sum(double x,double y) {
return x+y;
}
public static void main(String[] args) {
System.out.println("第一个求和方法:"+sum(1,2));
System.out.println("第二个求和方法:"+sum(1.0,2.0));
}
}
结果:
第一个求和方法:3
第二个求和方法:3.0
继承中方法的重载:
class Base {
public static int sum(int x,int y) {
return x+y;
}
}
class Sub extends Base {
public static int sum(int x,int y,int z) {
return x+y+z;
}
}
public class Main {
public static void main(String[] args) {
System.out.println("父类的求和方法: "+Base.sum(1,2));
System.out.println("子类的求和方法: "+Sub.sum(1,2,3));
}
}
结果:
父类的求和方法: 3
子类的求和方法: 6
注意:
1. 只有返回值不同,不构成方法的重载
2. 只有参数名称不同,不构成方法的重载
5.3 方法的重写
对于方法的重写,方法名、参数列表、返回值都要求要相同。
class Animal {
public static void eat() {
System.out.println("正在吃饭!");
}
}
class Cat extends Animal {
public static void eat() {
System.out.println("正在吃猫粮!");
}
}
public class Main {
public static void main(String[] args) {
Animal.eat();
Cat.eat();
}
}
结果:
正在吃饭!
正在吃猫粮!
重写需要注意的点:
- private修饰的方法不能重写
- static修饰的方法是不能重写的、
- 子类的访问修饰权限,要大于等于父类的权限
private < 默认 < protected < public - 被final修饰的方法,是不能被重写的,此时这个方法叫密封方法
六、数组的定义和使用
6.1 定义
-
适用于不使用初始化的数组。当数组特别长时,不初始化,值都是默认值。
数据类型[] 数组名 = new 数据类型[数组长度]
-
适合直接初始化数组,数组的长度由大括号内元素的个数决定。
数据类型[] 数组名 = {1,2,3}
6.2 遍历数组
for循环:
public class Main {
public static void main(String[] args) {
//我们在这里定义一个整形数组
int [] array = {1,2,3,4,5,6,7};
//通过for循环遍历
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
增强for循环:
public class Main {
public static void main(String[] args) {
//我们在这里定义一个整形数组
int [] array = {1,2,3,4,5,6,7};
//通过增强for循环遍历
for (int x : array) {
System.out.println(x);
}
}
}
Arrays.toString方法遍历:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
//我们在这里定义一个整形数组
int [] array = {1,2,3,4,5,6,7};
//通过Arrays.toString方法遍历
System.out.printf(Arrays.toString(array));
}
}
6.3 数组作为参数和返回值
我们在这里定义一个数组作为参数和返回值的函数,用于对整形数组进行排序,这里采用冒泡排序的思想。
代码如下:
import java.util.Arrays;
public class Main {
//我们在这里定义一个返回值和参数均为数组的函数,用于排序
public static int [] sort(int[] array) {
//冒泡排序
for (int i = 0; i < array.length-1; i++) {
for (int j = 0; j < array.length-1-i; j++) {
if(array[j]>array[j+1]) {
int temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
}
}
}
return array;
}
public static void main(String[] args) {
int [] array = {2,5,3,6,9,1};
int [] ret = sort(array);
System.out.println(Arrays.toString(ret));
}
}
6.4 操作数组的工具(Arrays)
- Arrays位于java.util包下(Arrays是一个操作数组的工具类)
- Arrays包含各种操作数组的方法(例如排序和搜索)。该类还包含一个静态工厂,允许将数组视为列表
- Arrays类里的方法都是静态方法可以通过Arrays.方法名()直接调用
--------------参考链接--------------
6.5 二维数组的使用
二维数组,就是数组中的每一个元素都是一维数组。
二维数组的静态初始化:
数组元素类型[][] 数组名 = new 数组元素类型[][]{数组1,数组2,数组3,...};
其中 new 数组元素类型 [ ] [ ] 可以省略。
二维数组的动态初始化:
数组元素类型[][] 数组名 = new 数组元素类型[x][y];
注意:
- x表示二维数组中有几个一维数组
- y表示每一个一维数组中有几个元素
- x必须存在,y可有可无(与C语言相反)
获取二维数组里的单个元素可以使用双重for循环,也可以使用双重增强for循环。
数组.length 可以获取二维数组的长度。
接下来我们使用循环来打印二维数组的每一个元素:
for循环:
public class Main6 {
public static void main(String[] args) {
int [][] array1 = {{1,2,3},{4,5,6},{7,8,9}};
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
System.out.println(array1[i][j]);
}
}
}
}
增强for循环:
public class Main6 {
public static void main(String[] args) {
int [][] array1 = {{1,2,3},{4,5,6},{7,8,9}};
for (int [] array : array1) {
for (int x : array) {
System.out.println(x);
}
}
}
}
七、类和对象
7.1 类
7.1.1 定义
class 类名 {
属性、成员属性、成员变量
行为、成员方法
}
7.1.2 成员变量
成员变量定义在类的内部、方法的外部
- 普通成员变量
普通成员变量属于对象,通过对象的引用和点号的结合进行访问
- 静态成员变量
静态成员变量是static修饰的,表面当前的成员变量是属于类变量;静态成员变量不依赖对象,直接通过类名和点号的结合进行调用
7.1.2 成员方法
- 普通成员方法
普通成员方法属于对象,通过对象的引用和点号的结合进行调用。普通成员方法内部可以使用静态成员方法。
- 静态成员方法
静态成员方法不依赖对象,直接通过类名和点号的结合进行调用,不能在静态方法当中使用非静态的成员变量。
7.2 对象
通过类可以实例化一个对象------->new。
Person person = new Person();
一个类可以实例化多个对象。这里person就是通过Person类实例化出来的对象。
注意:
- 当一个引用赋值为null时,代表这个引用不指向任何对象!
- 引用不能指向引用
7.3 this关键字
- 可以使用在实例方法当中,代表当前对象。【语法格式:this.】
- 可以使用在构造方法当中,通过当前的构造方法调用其他的构造方法。【语法格式:this(实参)】
- **this()**这种语法只能出现在构造方法中的第一行,表示调用其他的构造方法
7.4 构造方法
- 构造方法的方法名和类名一样,并且没有返回值
- 用于实例化对象的时候调用,同时可以初始化我们的成员变量
- 当我们没有添加任何的构造方法的时候,编译器会帮助我们提供一个不带参数的构造方法;当我们提供了任何的构造方法,编译器就不会再为我们提供构造方法了
- 构造方法可以重载
7.5 封装
- 封装指的是,将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
- 使用get和set方法对封装的数据进行访问和赋值
7.6 代码块
执行顺序:
- 静态代码块---->初始化静态的数据成员/提前准备一些数据
- 非静态代码块/实例代码块/构造代码块---->初始化非静态的数据成员
- 不带参数的构造方法
静态代码块只执行一次!
八、继承和多态
8.1 继承
-
继承的语法
class 子类 extends 父类 { }
-
继承时共性的抽取,达到了代码的复用
-
非静态的成员变量和成员方法都被继承了
注意:
- 使用extends继承指定的父类
- 一个子类只能继承一个父类
- 子类会继承父类的所有public的字段和方法
- 对于父类的private的字段和方法,子类中是无法访问的
- 子类的实例中,也包含着父类的实例,可以使用super关键字得到父类实例的引用
- 类可以继承一个普通类/抽象类,同时实现多个接口(implements A,B)
代码演示:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()) {
int x = scanner.nextInt();
int y = scanner.nextInt();
int z = scanner.nextInt();
Sub sub = new Sub(x, y, z);
System.out.println(sub.calculate());
}
}
}
class Base { //父类
private int x;
private int y;
//父类的构造方法
public Base(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
class Sub extends Base { //子类
private int z;
//子类构造方法
public Sub(int x, int y, int z) {
super(x,y); //此处要用super来调用父类的构造方法
this.z = z;
}
public int getZ() {
return z;
}
public int calculate() {
return super.getX() * super.getY() * this.getZ();
}
}
8.2 多态
多态:
当父类引用引用的对象不一样的时候,变现出的行为是不一样的。
向上转型:
表示往父类的方向转。
Cat cat = new Cat("猫咪");
Animal cat1 = new Cat("猫咪");
8.2.1 动态绑定
- 向上转型
- 重写
- 通过父类的引用调用父类和子类的重写的方法
代码实例:
class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println("我是一只小动物");
System.out.println(this.name+"正在干饭,并表示"+food+"很不错");
}
}
class Cat extends Animal{
public Cat(String name) {
super(name);
}
@Override
public void eat(String food) {
System.out.println("我是一只小猫");
System.out.println(this.name+"正在干饭,并表示"+food+"很不错");
}
}
class Bird extends Animal{
public Bird(String name) {
super(name);
}
@Override
public void eat(String food) {
System.out.println("我是一只小鸟");
System.out.println(this.name+"正在干饭,并表示"+food+"很不错");
}
public void fly() {
System.out.println(this.name + "正在飞");
}
}
public class Main{
public static void main(String[] args){
Animal animal1 = new Animal("圆圆");
animal1.eat("谷子");
System.out.println("====================");
Animal animal2 = new Bird("扁扁");
animal2.eat("谷子");
}
}
注意:
- 当在父类的构造方法当中去调用父类和子类重写的方法的时候,此时会调用子类的
- 当发生向上转型之后,此时通过父类的引用只能访问父类自己的成员,不能访问到子类特有的成员
九、抽象类和接口
9.1 抽象类
- 抽象类使用abstract修饰类
- 抽象类不能实例化
- 在抽象类中,可以有抽象方法或者非抽象方法
- 什么是抽象方法,一个方法被abstract修饰,没有具体的实现。只要包含抽象方法,这个类必须是抽象类
- 当一个普通类,继承了这个抽象类,必须重写抽象类当中的抽象方法
- 抽象类存在的最大意义就是 被继承
- 抽象方法不能被private,final,static修饰
- 当一个子类没有重写父类的抽象方法,可以把当前子类变为abstract修饰
- 抽象类当中不一定包含抽象方法
接下来我们实现一个抽象方法,代码如下:
import java.util.Scanner;
//定义一个抽象的父类
abstract class Base {
//定义一个抽象的方法,在这里抽象方法不能被实现
public abstract int sum();
public abstract int avg();
}
//继承抽象的父类,并实现其抽象方法(必须实现抽象方法)
abstract class Sub extends Base {
public static int sum(int x,int y) {
return x+y;
}
public static int avg(int x,int y) {
return (x+y)/2;
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
int sum = Sub.sum(a,b);
int avg = Sub.avg(a,b);
if(sum==0 || avg==0) {
System.out.println(0);
}else {
int ret = sum/avg;
System.out.println(ret);
}
}
}
9.2 抽象类和普通类的区别
- 抽象类不能实例化,普通类可以
- 抽象类当中,可以包含非抽象方法和抽象方法,但是普通类只能包含抽象方法
9.2 接口
- 使用关键字interface来定义接口
- 接口不能被实例化
- 接口当中的成员 默认是public static final
- 接口当中的方法 不写也默认是 public abstract 的
- 接口当中的方法 不能有具体的实现,但是从JDK8开始,可以写一个default修饰的方法
- 接口可以通过extends拓展多个接口的功能
- 先继承再实现接口
接下来我们来实现一个USB接口,代码如下:
USB接口
package Interface_Use;
//USB接口
public interface USB {
void openDevice();
void closeDevice();
}
Computer类
package Interface_Use;
//笔记本类:使用USB设备
public class Computer {
public void powerOn() {
System.out.println("打开电脑!");
}
public void powerOff() {
System.out.println("关闭电脑!");
}
public void usDevice(USB usb) {
usb.openDevice();
if(usb instanceof Mouse) {
Mouse mouse = (Mouse)usb;
mouse.click();
} else if(usb instanceof KeyBoard) {
KeyBoard keyBoard = (KeyBoard)usb;
keyBoard.input();
}
usb.closeDevice();
}
}
Mouse类
package Interface_Use;
public class Mouse implements USB{
@Override
public void openDevice() {
System.out.println("打开鼠标!");
}
@Override
public void closeDevice() {
System.out.println("关闭鼠标!");
}
public void click() {
System.out.println("点击鼠标!");
}
}
KeyBoard类
package Interface_Use;
public class KeyBoard implements USB{
@Override
public void openDevice() {
System.out.println("打开键盘!");
}
@Override
public void closeDevice() {
System.out.println("关闭键盘!");
}
public void input() {
System.out.println("键盘输入!");
}
}
TestUSB类
package Interface_Use;
public class TestUSB {
public static void main(String[] args) {
Computer computer = new Computer();
computer.powerOn();
System.out.println("================");
//使用鼠标设备
computer.usDevice(new Mouse());
System.out.println("================");
//使用键盘设备
computer.usDevice(new KeyBoard());
System.out.println("================");
computer.powerOff();
}
}
注意:
十、认识String类
10.1 String的三种构造方式
-
直接构造
String strs = "helloworld";
-
将字符串封装成字符串对象
String strs = new String(""helloworld);
-
将字符串的数据封装成字符串对象
char[] array = {'h','e','l','l','o'}; String strs = new String(array);
10.2 字符串常量池
- 字符串常量池是存在与堆上单独的一块空间
- 双引号引起来的,统一放到常量池
- 如果常量池有,那么就不再额外存储了
10.3 String不可变性
String 类是引用类型,是不可变的。StringBuffer和StringBuilder是可变的。
例如:
String str1 = "abc";
String str2 = new String("abc");
如果这里修改str2的值,str1的值并不会改变。
接下来我们画一个内存分配图展现两个字符串的存储:
10.4 charAt的使用
charAt是属于String类下的一个方法,可以用来打印字符串里的每一个字符。
代码如下:
import java.lang.String;
public class Main {
public static void main(String[] args) {
String strs = "hello";
for (int i = 0; i < strs.length(); i++) {
// i代表的是下标
System.out.println(strs.charAt(i));
}
}
}
十一、认识异常
异常其实就是类,其分为编译时异常(受查异常)和运行时异常(非受查异常)。
在java中,异常处理主要的5个关键字:throw、try、catch、final、throws。
接下来我们来实现一个自定义异常:
PasswordExption类
public class PasswordExption extends RuntimeException {
}
UsernameExption类
public class UsernameExption extends RuntimeException{
}
Test类
public class Test {
private String name = "admain";
private String passnum = "123456";
public void login(String name,String passnum) throws UsernameExption,PassnumExption {
if(!this.name.equals(name)) {
System.out.println("用户名错误");
throw new UsernameExption();
}
if(!this.passnum.equals(password)) {
System.out.println("密码错误");
throw new PassnumExption();
}
}
public static void main(String[] args) {
Test test = new Test();
try {
test.login("admain","123");
}catch (UsernameExption e) {
e.printStackTrace();
System.out.println("用户名异常!");
}catch (PassnumExption e) {
e.printStackTrace();
System.out.println("密码异常!");
} finally {
}
}
}
注意:
- 程序先执行try中的代码
- 如果try中的代码出现异常,就会结束try中的代码,看和catch中的异常类型是否匹配
- 如果找到匹配的数据类型,就会执行catch中的代码
- 如果没有找到匹配的异常类型,就会将异常向上传递给上层调用者
- 无论是否找到匹配的异常类型,finally中的代码都会被执行到(在该方法结束之前执行)
- 如果上层调用者也没有处理异常,就继续向上传递,如果一直到main方法也没有合适的代码处理异常,就会交给JVM进行处理,此时程序就会异常终止
总结
以上就是我今天要讲的内容,本文梳理了javase中的重要知识,如有不正,还望大家指出修改!