JavaSE基础05
多态
package com.OOP.demo08;
public class Person {
public void work(){
System.out.println("父亲白天要上班");
}
public void eat() {
System.out.println("父亲中午吃烤肉");
}
}
package com.OOP.demo08;
public class Student extends Person{
public void course() {
System.out.println("学生白天要上课");
}
@Override
public void eat() {
System.out.println("儿子中午吃米饭");
}
}
package com.OOP;
import com.OOP.demo07.A;
import com.OOP.demo07.B;
import com.OOP.demo08.Person;
import com.OOP.demo08.Student;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
// new Student();
// new Person();
//可以指向的引用类型就不确定了:父类的引用指向子类
//Student 能调用的方法都是自己的或者继承父类的
Student student01 = new Student();
//Person 父类型,可以指向子类,但是不能调用子类独有的方法
//换句话说:可以调用自己有而子类没有的方法
Person person01 = new Student();
//对象能执行那些方法,主要看对象左边的类型,和右边关系不大
person01.work();
person01.eat(); // 子类重写了父类的方法,调用子类的方法
((Student) person01).course();//父类中没有的方法,将父类对象强制转换成子类类型
System.out.println();
student01.work();// 子类中没有的方法,子类对象调用父类的方法
student01.course();
student01.eat();
}
}
/*
多态的注意事项:
1. 多态是方法的多态,属性没有多态
2. 父类和子类,有联系:存在继承关系 类型转换异常! ClassCastException!
3. 存在条件: 继承关系,方法需要重写,父类的引用指向子类类型 Father f1 = new Son();
1. static 方法,属于类,不属于实例,不能被重写
2. final 常量
3. private 方法
*/
instancesof
instancesof
System.out.println(X instancesof Y); //输出结果为 布尔类型true、false
// 判断条件:X、Y之间存在联系:父子关系...
// X一般为子类 Y一般为父类
类型转换
package com.OOP.demo09;
public class Person {
public void eat(){
System.out.println("人吃饭");
}
public void drink(){
System.out.println("人喝水");
}
public void sleep(){
System.out.println("人睡觉");
}
}
package com.OOP.demo09;
public class Student extends Person{
public void run(){
System.out.println("学生会在大课间进行跑步锻炼");
}
@Override
public void eat() {
System.out.println("学生中午在餐厅无法吃到好吃的饭菜");
}
}
package com.OOP;
import com.OOP.demo09.Person;
import com.OOP.demo09.Student;
public class Application {
public static void main(String[] args) {
//低 转 高
//子类 转 父类 向上转型
Person person = new Student();
person.eat();
person.drink();
person.sleep();
//高 转 低
//父类 转 子类 向下转型 强制转换
//将这个对象转换成Student类型,我们就可以使用Student类型的方法了
//但是在 高转低之后 转换过后的高类型的对象无法使用低类型中独有的方法
// 父类转换成子类之后 转换过后的父类对象无法使用子类中独有的方法
Student student = (Student) person;
student.run();
//组合式
((Student) person).run();
Student student1 = new Student();
Person person1 = student1; //父类的引用指向子类对象
}
}
/*
1. 父类的引用指向子类对象
2. 把子类转换为父类:向上转型
3. 把父类转换成子类:向下转型
向下转型的前提是已经发生了向上转型,向下转型是再次转回来而已
4. 方便方法的调用,减少重复代码,简洁
*/
Static关键字
package com.OOP.demo10;
//static 跟类一起加载
public class Student {
private static int age; //静态变量 多线程
private double score; //非静态变量
public static void run(){
//在static方法中可以直接调用static方法,但是不能直接调用非static方法
System.out.println("学生在大课间要进行跑步活动");
}
public void go(){
run(); //static方法可以在非static方法中直接调用
System.out.println("学生在课件或者体育课上可以选择性的进行跑圈运动锻炼身体");
}
public static void main(String[] args) {
System.out.println(Student.age);
Student student = new Student();
System.out.println(student.score);
System.out.println(student.age);
new Student().go();
Student.run();
run();
}
}
package com.OOP.demo10;
public class Person {
// 2.匿名代码块,在构造方法之前执行
// 可以通过匿名代码块赋初值
{
System.out.println("匿名代码块");
}
// 1. 静态代码块跟类一起执行,它是最早执行的,而且static只执行一次
// 而其他的在对象一创建的时候,就执行一次匿名代码块,在往后执行构造方法
static {
System.out.println("静态代码块");
}
// 3. 构造方法
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person = new Person();
System.out.println("===========");
Person person1 = new Person();
}
}
package com.OOP.demo10;
//静态导入包 可以省略类名不写,直接写方法名
import static java.lang.Math.PI;
import static java.lang.Math.random;
public class Text {
public static void main(String[] args) {
random();
System.out.println(PI);
}
}
final关键字注意:
被final修饰过后的类:会成为“最终类、终极类”,无法被继承
抽象类
package com.OOP;
//abstract 抽象类 extends 但是类有单继承的局限性 接口可以实现多继承
public abstract class Action {
//约束--写框架--想要有人帮我们实现
//abstract,抽象方法,只有方法名字,没有方法实现(方法体)
public abstract void doSomething();
/*
抽象类特点:
1. 抽象类不能new,只能靠它的子类去实现它:约束!
2. 抽象方法里面也可以有普通方法
3. 但是 一但类里面有一个抽象方法,该类就是抽象类
思考:
抽象类既然不能new,那它存在构造器吗?
抽象类存在的意义?
打游戏创建角色,如果角色非常复杂,反复创建的话会比较麻烦
我们可以把角色的一些公有属性抽象出来
每创建一个角色就去继承这些抽象类
然后去自动重写它的一些方法
提高开发效率!
*/
}
package com.OOP.demo10;
import com.OOP.Action;
//继承了抽象类的子类必须实现抽象类的所有方法,除非继承抽象类的子类也是抽象类,那就要它的子子类来实现
public class A extends Action {
@Override
public void doSomething() {
System.out.println("约束--我只写框架--希望有人可以替我实现方法");
}
}
接口
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有
- 接口:只有规范!自己无法写方法~~专业的约束! 约束与实现分离:面向接口编程
注意:接口的地位!
- 接口就是规范,定义的是一直规则,体现了现实世界中 "如果你是...则必须能..." 的思想。 如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你是好人,则必须干掉坏人。如果你是坏人,则必须欺负好人
- 接口的本质就是契约,就像我们人间的法律一样。制定好后大家都遵守
- OO的精髓,是对 对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只是针对具备了抽象能力的语言(c++,java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象
声明类的关键字是:Class 声明接口的关键字是:interface 类与接口同样重要,甚至比类更重要
接口的作用
接口的作用:
1. 约束
2. 定义一些方法,让不同的人实现
3. 方法都是 public abstract
4. 属性都是 public abstract final
5. 接口不能被实例化,接口中没有构造方法
6. 通过implements关键字可以实现多个多个接口
7. 必须要重写接口中的方法
package com.OOP.demo12;
//抽象的思维--java
//interface 接口定义的关键字,接口都需要实现类
public interface UserService {
//尽量不要在接口中定义属性
//在接口中定义的属性都是常量:public static final
int AGE = 99;
//接口中的所有定义的方法都是抽象的
//自动加上public abstract,自己可以不用写,只写 方法返回值类型、方法名、参数列表
//在接口中只能存在public ,其他任何权限修饰符都会报错
int add(int number_a,int number_b);
int subtract(int number_a,int number_b);
int multiply(int number_a,int number_b);
int division(int number_a,int number_b);
}
package com.OOP.demo12;
public interface TimeService {
void timer();
}
package com.OOP.demo12;
//类 通过abstract关键字 将普通类声明成抽象类 通过extends关键字 可以继承抽象类,但是只能单继承
//类 通过implements关键字 可以实现接口,可以实现多个接口,可以利于接口实现多继承
//实现了接口的类,就需要重写接口中的全部方法
public class UserServiceImpl implements UserService,TimeService{
@Override
public int add(int number_a, int number_b) {
int sum = 0;
sum = number_a + number_b;
return sum;
}
@Override
public int subtract(int number_a, int number_b) {
int Algorithms = 0;
/* if (number_a > number_b){
Algorithms = number_a - number_b;
}else{
Algorithms = number_b - number_a;
}
*/
/* Algorithms = number_a - number_b;
if (Algorithms < 0) {
Algorithms = -Algorithms;
}else {
Algorithms = Algorithms;
}
*/
Algorithms = Math.abs(number_a - number_b);
if (number_a < number_b){
Algorithms = -Algorithms;
}else {
Algorithms = Algorithms;
}
return Algorithms;
}
@Override
public int multiply(int number_a, int number_b) {
int Algorithms = 0;
/* Algorithms = number_a * number_b;
if (number_a == 0 && number_b == 0){
System.out.println("您输入的数字没有计算意义");
}
if (number_a == 0 || number_b == 0) {
Algorithms = 0;
}
*/
Algorithms = number_a * number_b;
if (number_a == 0 || number_b == 0){
Algorithms = 0;
}
return Algorithms;
}
@Override
public int division(int number_a, int number_b) {
int Algorithms = 0;
while (number_b != 0) {
Algorithms = number_a / number_b;
break;
}
if (number_b == 0){
System.out.println("0不能作除数");
}
return Algorithms;
}
@Override
public void timer() {
}
}
package com.OOP;
import com.OOP.demo12.UserServiceImpl;
public class Application {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
System.out.println(userService.subtract(30, 20));
System.out.println(userService.multiply(1, 2));
System.out.println(userService.division(10, 0));
}
}
N种内部类
package com.OOP.demo13;
public class Outer {
private int id = 10;
public void out(){
System.out.println("这是外部类的方法");
}
//成员内部类
//成员内部类加上static就是静态内部类
//静态内部类无法获得外部类的私有属性,除非把外部类的属性也改为static
public class Inner {
public void in(){
System.out.println("这是内部类的方法");
}
//通过内部类获得外部类的私有属性
public void getID() {
System.out.println(id);
}
public void getOut(){
out();
}
}
}
//一个java类中可以有多个class类,但是只能有一个public class类
class A {
public static void main(String[] args) {
//局部内部类
//声明在方法中的变量成为局部变量,声明在方法中的类称为局部内部类
class Inner {
}
}
}
package com.OOP.demo13;
public class Text {
public static void main(String[] args) {
//有对象名的初始化
Apple apple = new Apple();
//没有对象名字的初始化 匿名内部类
//匿名对象的使用,不用将实例保存在变量中
new Apple().eat();
//匿名内部类
new UserService(){
@Override
public void hello() {
}
};
}
}
class Apple {
public void eat() {
System.out.println("1");
}
}
interface UserService {
void hello();
}
package com.OOP;
import com.OOP.demo13.Outer;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过这个外部类来实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getID();
inner.getOut();
}
}
异常机制
异常处理机制
1. 抛出异常
package com.exception;
public class Text03 {
public static void main(String[] args) {
int number_a = 10;
int number_b = 0;
//Ctrl + Alt + T 快捷键生成代码块包裹代码
try {
if (number_b == 0){
throw new ArithmeticException(); //主动抛出异常
}
System.out.println(number_a/number_b);
} catch (Exception e) {
System.out.println("除数不能为0");
e.printStackTrace(); //打印错误的栈信息
} finally {
System.out.println("除数不能为0,请重新出入");
}
}
}
package com.exception;
public class Text04 {
public static void main(String[] args) {
try {
new Text04().text(2,0);
} catch (ArithmeticException e) {
e.printStackTrace();
}
}
//假设这个方法中,处理不了这个异常。我们在 方法上抛出异常 使用throws关键字上抛异常
public void text(int a,int b) throws ArithmeticException{
if(b == 0){ //throw, throws
throw new ArithmeticException(); //使用throw关键字主动抛出异常,一般在方法中使用
}
System.out.println(a/b);
}
}
2. 捕获异常
package com.exception;
public class Text {
public static void main(String[] args) {
int a = 1;
int b = 0;
try { //try监控区域
System.out.println(a/b);
}catch (ArithmeticException e){ //catch 捕获异常
System.out.println("程序出现异常,0不能作除数");
}finally { //处理善后工作,可以不写,但是try,catch必须写
System.out.println("finally");
}
//finally一般用于最后 IO流的资源关闭
//而且在finally执行完成后再进行报错爆红
}
}
package com.exception;
public class Text {
public static void main(String[] args) {
try { //try监控区域
new Text().a();
}catch (Throwable e){ //catch 捕获异常
System.out.println("程序出现异常,程序无法终止");
}finally { //处理善后工作,可以不写,但是try,catch必须写
System.out.println("finally");
}
//finally一般用于最后 IO流的资源关闭
//而且在finally执行完成后再进行报错爆红
}
public void a(){
b();
}
public void b(){
a();
}
}
package com.exception;
public class Text {
public static void main(String[] args) {
int a = 1;
int b = 0;
try { //try监控区域
System.out.println(a/b);
}catch (Error e){ //catch(想要捕获的异常类型) 捕获异常
System.out.println("Error");
}catch (Exception e){
System.out.println("Exception");
}catch (Throwable t){
System.out.println("Throwable");
}finally { //处理善后工作,可以不写,但是try,catch必须写
System.out.println("finally");
}
//finally一般用于最后 IO流的资源关闭
//而且在finally执行完成后再进行报错爆红
}
public void a(){
b();
}
public void b(){
a();
}
}
//假设要捕获多个异常,要从小到大进行捕获
//catch捕获的异常的范围 从上到下 依次扩大,不能颠倒
package com.exception;
public class Text02 {
public static void main(String[] args) {
int a = 1;
int b = 0;
//Ctrl + Alt + T 快捷键生成代码块包裹代码
try {
System.out.println(a/b);
} catch (Exception e) {
System.out.println("除数不能为0");
System.exit(0); //如果出现异常,退出程序
e.printStackTrace(); //打印错误的栈信息
} finally {
System.out.println("除数不能为0,请重新出入");
}
}
}
3.异常处理的五个关键字
try,catch,finally,throw,throws
自定义异常类
package com.exception.demo02;
//自定义的异常类 要继承Exception类
public class MyException extends Exception {
//传递数字 > 10
private int detail;
public MyException(int a) {
this.detail = a;
}
//toString: 异常的打印信息
@Override
public String toString() {
return "MyException{" + detail + '}';
}
}
package com.exception.demo02;
public class Text {
//可能会存在异常的方法
public static void text(int a) throws MyException {
System.out.println("传递的参数为 " + a);
if (a > 10){
throw new MyException(a); //抛出
}
System.out.println("OK");
}
public static void main(String[] args) {
try {
text(1);
} catch (MyException e) {
//增加一些处理异常的代码块
//if(a > 10){
//a--;
//}
System.out.println("MyException =>" + e);
}
}
}
实际工作当中的异常经验总结
- 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
- 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
- 对于不确定的代码,也可以加上try-catch,处理潜在的异常
- 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句块去释放占用的资源

浙公网安备 33010602011771号