【Java入门到精通】(三)Java基础语法(下)
一、面向对象(类和对象)
1.1 万事万物皆对象
类:对对象向上抽取出像的部分、公共的部分以此形成类,类就相当于一个模板。
对象:模板下具体的产物可以理解为具体对象,对象就是一个一个具体的实例,就相当于这个模板下具体的产品。
Java中一般先定义类,再创建对象
1.2 类和对象的关系
(1)类的定义
- 给类起一个见名知意的名字,首字符大写,驼峰命名原则,
- 类的特性编写,特性即类的属性部分。
- 类的行为编写,行为即类的方法部分。
(2)类和对象的创建以及使用
类的定义
public class Person {// 特性编写-属性-名词(只定义和业务逻辑相关的代码)String name; // 姓名int age; // 年龄double height; // 身高// 行为编写-方法-动词// 定义一个学习的方法public void study() {System.out.println("study>>>>>>");}
}
对象的创建和使用类
public class Test {// 程序的入口public static void main(String[] args) {// 对Person类的对象进行创建:创建了一个Person对象,名字叫p1Person p1 = new Person();// 对属性进行赋值操作p1.name = "张三";p1.age = 18;p1.height = 178.5;// 读取属性System.out.println(p1.name);System.out.println(p1.age);// 调用对象的方法p1.study();}
}
二、构造器
2.1 构造器的作用
对于一个类来说,一般有三种常见的成员:属性、方法、构造器。这三种成员都可以定义零个或多个。
构造方法也叫构造器,是一个创建对象时被自动调用的特殊方法,用于对象的初始化。Java通过new关键字来调用构造器,从而返回该类的实例。
2.2 构造器声明格式
若无参数列表,称之为无参构造器(空构造器)
若有参数列表,称之为有参构造器
2.3 构造器四要点
- 构造器的方法名必须和类名一致
- 构造器通过new关键字调用
- 构造器不能定义返回值类型,不能在构造器里使用return关键字来返回某个值。
- 如果我们没有定义构造器,则编译器会自动定义一个无参的构造方法。如果已定义则把编译器不会自动添加
2.4 构造器的重载
构造方法也是方法,只不过有特殊的作用而已。与普通方法一样,构造方法也可以重载。
2.5 创建构造器的快捷键
8Alt + Insert
2.6 代码示例
Person类
// 特性编写-属性-名词(只定义和业务逻辑相关的代码)
String name; // 姓名
int age; // 年龄
double height; // 身高// 行为编写-方法-动词
// 定义一个学习的方法
public void study() {System.out.println("study>>>>>>");
}
// 定义一个构造器
public Person() {System.out.println("调用了一个空构造器");
}
// 重载一个构造器
// 构造器的参数名字:如果和属性名字重名,就会发生就近原则
// 如果重名以后,你想给属性赋值,那么就在想要表达属性的变量前加上 this. 修饰
public Person(int age, String name, double height) {this.age = age;this.name = name;this.height = height;
}
Test02对象
public class Test02 {public static void main(String[] args) {// 创建一个Person类的对象/* new Person()解释Person():空的构造方法new关键字:对方法进行调用=》构造器作用:底层会帮我们创建对象,在创建对象之后进行初始化操作如果一个类没有显示编写构造器的话,那么系统会为这个类默认分配一个空构造器调用构造器以后,对对象进行初始化操作,将对象的地址返回给p尽量要保证空构造器的存在,因为某些框架底层需要空构造器,如果你没有添加就会报错*//*原始写法Person p = new Person();p.age = 18;p.name = "小张";p.height = 180.6;Person p2 = new Person();p2.age = 18;p2.name = "小李";p2.height = 160.6;*/// 简便写法Person p = new Person(18,"小张",180.6);System.out.println(p.age);Person p2 = new Person(30, "小李",160.6);System.out.println(p2.age);// 如果一个类中有构造器,那么系统就不会为你分配默认的构造器// Person p3 = new Person(); // 会报错}}
三、面向对象(封装)
3.1 封装的思想
我们程序设计追求“高内聚,低耦合”。
- 高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
- 低耦合:仅对外暴露少量的方法用于使用。
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性,提高程序的安全性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装的设计思想。
3.2 代码
Gril类
public class Gril {// 属性private int age; // private表示私有属性,只能在内部访问// 封装思想的使用:// 给age提供一个赋值方法:public void setAge(int age) {if (age > 30) {this.age = 18;} else {this.age = age;}}// 给age提供一个读取的方法public int getAge(){return age;}
}
Test对象调用Gril类
public class Test {public static void main(String[] args) {// 创建对象Gril g = new Gril();g.setAge(18);System.out.println(g.getAge());}
}
3.3 上述封装代码的解释
上述代码以属性为案例进行封装:
(1)将属性私有化,被private修饰--》加入权限修饰符(一旦加入了权限修饰符,其他人就不能随意的获取这个属性)
(2)提供public修饰的方法让别人来访问/使用
(3)即使外界可以通过方法来访问属性了,但是也不能随意访问,因为程序员可以在方法中加入限制条件。
四、面向对象(继承)
4.1 类是对对象的抽象
4.2 继承是对类的抽象
4.3 继承的格式和好处
(1)继承的格式
子类 extends 父类
public class student extends Person {}
(2)继承的好处
- 提高了代码的复用性;
- 便于代码的扩展;
- 为了多态的使用,是多态使用的前提
4.4 代码示例
Person继承类
public class Person {// 父类的公共属性:private int age;private String name;private double height;//父类的公共方法:public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}// 吃饭public void eat() {System.out.println("人类可以吃饭!!");}//睡觉public void sleep() {System.out.println("人类可以睡觉!!");}//喊叫public void shout() {System.out.println("人类可以喊叫!!");}
}
Student类
public class Student extends Person {// 定义子类额外的、扩展的属性private int sno;// 定义子类额外的、扩展的方法public int getSno() {return sno;}public void setSno(int sno) {this.sno = sno;}// 学习:public void study() {System.out.println("学生可以学习");}
}
Test对象
public class Test {public static void main(String[] args) {// 定义一个子类具体的对象:Student s = new Student();s.setSno(10000);s.setAge(18);s.setName("张三");s.setHeight(180.3);s.study();s.eat();s.shout();s.sleep();}
}
4.5 方法的重写
方法的重写是基于继承来的
方法重写的定义:
发生在子类和父类中,当子类对父类提供的方法不满意的时候,要对父类的方法进行重写。
一旦子类对父类的方法进行了重写,对象访问的时候,就只能访问到子类的方法(就近原则)。
方法的重写有严格的格式要求:
子类的方法名和父类必须一致,参数列表(个数,类型,顺序)也要和父类一致。
代码
Person继承类
public class Person {public void eat(){System.out.println("人可以吃饭");}
}
Student类
public class Student extends Person {// 方法的重写public void eat(){System.out.println("我喜欢吃烧烤");}
}
Test对象
public class Test {public static void main(String[] args) {// 创建一个Student具体的对象Student s = new Student();s.eat();}
}
面试常问:
重载和重写有什么区别?
重载:在同一个类中,当方法名相同,形参列表不同的时候,多个方法构成了重载。
重写:在不同的类中,子类对父类提供的方法不满意,对父类的方法进行重写。
五、面向对象(多态)
5.1 多态的概念
多态:通俗来所,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。同一种行为,不同的子类呈现出来的状态是不同的。
ps:多态跟属性无关,多态指的是方法的多态,而不是属性的多态。
5.2 多态的三要素和好处
多态三要素:继承、重写、父类引用指向子类对象
多态的好处:提高代码扩展性
// 这里没太理解,而且比较乱,可以看一下项目中的java10下面的示例
六、异常处理
6.1 什么是异常
异常就是在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序。
- 所需要的文件找不到
- 网络连接不同或中断
- 算术运算错(被零除...)
- 数组下标越界
- 装载一个不存在的类或者对null对象操作
- 类型转换异常
- ........
Java提供异常处理机制。它将异常处理代码和业务代码分离,使程序更优雅,更好的容错性,高健壮性。
Java的异常处理是通过5个关键字来实现的:try、catch、finally、throw、throws
6.2 程序中异常演示
6.3 try-catch-finally
public static void main(String[] args) {try {// 求两个数的商int num1 = 12;int num2 = 2;System.out.println("两个数的商为:"+ num1/num2);} catch (Exception ex){System.out.println("你的程序出现了错误"+ ex);} finally {System.out.println("程序无论是否出现异常,这里的逻辑都必须执行");}System.out.println("上面是两个数相除的逻辑案例1");
}
try-catch执行情况
情况1:try块中代码没有出现异常
不执行catch块代码,执行catch块后边的代码
情况2:try块中代码出现异常,catch中异常类型匹配(相同或者父类)
Java会生成相应的异常对象,Java系统寻找匹配的catch块,执行catch块后面的代码。try块中尚未执行的语句不会执行。
情况3:try块代码出现异常,catch中异常类型不匹配
不执行catch块代码,不执行catch块后面的代码,程序会中断运行
catch块中如何处理异常
其中一种方式:自定义内容输出
6.4 throw/throws
throw/throws的使用
public class Test02 {public static void main(String[] args) {try {devide();} catch (Exception e) {System.out.println("在调用时处理异常");}}// 提取一个方法:两个数相除操作public static void devide() throws Exception {int num1 = 12;int num2 = 0;if(num2 == 0){// 人为制造一个异常/** 第一种抛异常的方式:try {throw new Exception();} catch (Exception e) {throw new RuntimeException(e);}*/throw new Exception();}System.out.println("两个数的商是" + num1/num2);}
}
throw和throws的区别
(1)位置不同
throw:方法内部
throws:方法的签名处,方法的声明处
(2)内容不同:
throw+异常对象
throws+异常的类型
(3)作用不同:
throw:异常出现的源头,制造异常。
throws:在方法的声明处,告诉方法的调用者,这个方法中可能会出现我声明的这些异常。然后调用者对这个异常进行处理:要么自己处理,要你再继续向外抛出异常。
七、集合
7.1 对比数组的缺点引入集合
(1)数组一旦指定了长度,那么长度就被确定了,不可以更改。
(2)删除、增加元素效率低(如果改变数组中其中一项,后面的项都要跟着变)
(3) 数组中实际元素的数量是没法获取到的,没有提供对应的方法或者属性来获取。
(4)数组存储:有序,可重复,对于无序的,不可重复的场合数组不能满足要求。
7.2 集合体系预览
7.3 ArrayList集合的使用
public static void main(String[] args) {// 定义一个集合ArrayList<String> list = new ArrayList<String>();// 增加元素:list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");System.out.println(list); // [aaa, bbb, ccc, ddd]// 删除元素:list.remove("ccc");System.out.println(list); // [aaa, bbb, ddd]// 修改元素:list.set(0, "eee");System.out.println(list); // [eee, bbb, ddd]// 查看元素:System.out.println(list.get(0)); // eee// 遍历当前集合// 使用普通的for循环for (int i = 0; i < list.size()-1; i++) {System.out.println(list.get(i));}
}
增加元素 | list.add("aaa"); |
删除元素 | list.remove("ccc"); |
修改元素 | list.set(0, "eee"); |
查找元素 | System.out.println(list.get(0)); |
遍历元素 | for (int i = 0; i < list.size()-1; i++) { |
八、项目总结实战
8.1 需求设计
项目名称:小张书城
项目需求设计:
项目任务 | 涉及技能点 |
---|---|
1、展示书籍 2、上新书籍 3、下架书籍 4、推出应用 | 用户交互-键盘录入 分支结构、循环结构 面向对象思维封装对象(如何合理定义类) 集合的使用 |
8.2 项目代码实现
Books集合
public class Books {// 书籍相关// 书籍类的 属性// private修饰符:只允许内部访问,外部无法访问该属性// 书籍编号private int bNo;// 书籍名称private String bName;// 书籍作者private String bAuthor;//快捷键:alt + insert 快速创建get和set方法public int getbNo() {return bNo;}public void setbNo(int bNo) {this.bNo = bNo;}public String getbAuthor() {return bAuthor;}public void setbAuthor(String bAuthor) {this.bAuthor = bAuthor;}public String getbName() {return bName;}public void setbName(String bName) {this.bName = bName;}// 构造器public Books(int bNo, String bName, String bAuthor) {this.bNo = bNo;this.bName = bName;this.bAuthor = bAuthor;}// 空构造器public Books() {}
}
Test对象
package com.study.java13;
import java.awt.print.Book;
import java.util.ArrayList;
import java.util.Scanner; // 告诉程序这个类在什么位置/*
【小张书城】项目功能规划:
1.展示书籍
2.上新书籍书籍信息:书籍编号 书籍名称 书籍作者01 小张的Java之路 小张快跑 ----》 封装成一个具体的书籍对象 ---》类:书籍
3.下架书籍
4.退出应用*/
public class Test {public static void main(String[] args) {// 创建一个集合:用于存放相同的个体(列表用来存放书籍)--》书籍对象 --》注意作用范围:将list放在循环外面ArrayList list = new ArrayList(); // 空集合while (true){// 打印菜单:System.out.println("-------欢迎来到【小张书城】-------");System.out.println("1.展示书籍");System.out.println("2.上新书籍");System.out.println("3.下架书籍");System.out.println("4.退出应用");// 借助Scanner类:Scanner sc = new Scanner(System.in); // 扫描键盘录入事件类// 给一个友好的提示System.out.println("请录入你想要执行的功能的序号:");// 利用键盘,录入序号:int choice = sc.nextInt(); // 接收键盘录入的事件// 根据choice录入的功能序号,进行后续的判断if(choice == 1){System.out.println("<展示书籍>");// 展示书籍(对集合进行遍历查看)for (int i = 0; i < list.size(); i++) {Books b = (Books)(list.get(i)); // Java 语言中的类型转换System.out.println(b.getbNo() + "------" + b.getbName() + "------" + b.getbAuthor() + "------");}}if(choice == 2){System.out.println("<上新书籍>");// 从键盘录入书籍信息System.out.println("请录入书籍编号:");int bNo = sc.nextInt(); // 获取家键盘int类型数据System.out.println("请录入书籍名称:");String bName = sc.next(); //获取家键盘String类型数据System.out.println("请录入书籍作者:");String bAuthor = sc.next(); //获取家键盘String类型数据// 每上新一本书,就要创建一个书籍对象Books b = new Books();b.setbNo(bNo);b.setbName(bName);b.setbAuthor(bAuthor);list.add(b); // 添加个体到集合中去}if(choice == 3){System.out.println("<下架书籍>");// 录入要下架的书籍的编号System.out.println("请录入你要下架的书籍的编号:");int deNo = sc.nextInt();// 下架编号对应的书籍for (int i = 0; i < list.size(); i++) {Books b = (Books)(list.get(i));if(b.getbNo() == deNo){ // 如果遍历的书籍编号和录入的要删除的书籍编号一致,那么从集合中移除该书籍即可list.remove(b);System.out.println("书籍下架成功");break; // 如果下架成功,就停止遍历,不需要后续的遍历}}}if(choice == 4){System.out.println("<退出应用>");break; // 停止正在执行的循环}}}
}