instanceof和类型转换
instanceof可以判断两个类之间是否存在父子关系
package com.OOP;
import com.OOP.Demo06.Person;
import com.OOP.Demo06.Student;
import com.OOP.Demo06.Teacher;
public class Application {
public static void main(String[] args) {
Object object=new Student();
System.out.println(object instanceof Student);
System.out.println(object instanceof Person);
System.out.println(object instanceof Object);
System.out.println(object instanceof Teacher);
System.out.println(object instanceof String);//不报错因为String类是Object类的子类
System.out.println("=======================");
Person person=new Student();
System.out.println(person instanceof Student);
System.out.println(person instanceof Person);
System.out.println(person instanceof Object);
System.out.println(person instanceof Teacher);
// System.out.println(person instanceof String);编译报错,因为Person类与String类没有半毛钱关系
System.out.println("=======================");
Student student=new Student();
System.out.println(student instanceof Student);
System.out.println(student instanceof Person);
System.out.println(student instanceof Object);
//System.out.println(student instanceof Teacher);编译报错,因为student类与Teacher类之间不存在继承关系
// System.out.println(person instanceof String);编译报错,因为Student类与String类没有半毛钱关系
}
}
/*
true
true
true
false
false
=======================
true
true
true
false
=======================
true
true
true
*/
X instanceof Y能不能编译通过,取决于X与Y之间有没有继承关系
子类可以直接调用父类的方法,父类想要调用子类的方法,需要强制转换成子类,才能调用
子类转换成父类,可能会丢失一些自己的方法
package com.OOP;
import com.OOP.Demo06.Person;
import com.OOP.Demo06.Student;
public class Application {
public static void main(String[] args) {
//类型之间的转换:父 子
//高 低
Person obj=new Student();
//从父类往子类转换需要强制转换,只有强制转换后,才可以调用子类的方法
Student student = (Student) obj;
student.go();
}
}
/*
go
*/
多态总结
- 存在的条件:父类引用指向子类的对象
- 把子类换换成父类,向上转型
- 把父类转换成子类,向下转型:强制转换
- 方便方法的调用,减少重复的代码
static字符串详解
package com.OOP.Demo07;
//static
public class Student {
private static int age;//静态变量,可以直接通过类名调用
private double score;//非静态变量,只能通过实例换对象调用
public void run(){
}
public static void go(){
}
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1.score);
System.out.println(Student.age);
System.out.println("==================");
//静态方法可以直接调用
Student.go();
go();
}
}
package com.OOP.Demo07;
public class Person {
//3.其次
{
//代码块(匿名代码块)
System.out.println("匿名代码块");
}
//1.最先执行,只执行依次
static {
//静态代码块
System.out.println("静态代码块");
}
//2.第三
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.Demo07;
//静态导入包
import static java.lang.Math.PI;
import static java.lang.Math.random;
public class Test {
public static void main(String[] args) {
System.out.println(random());//随机数
System.out.println(PI);
}
}
通过final类修饰的类不能被继承
抽象类
package com.OOP.Demo08;
//abstract 抽象类:抽象类是类,只能单继承,但是接口可以多继承
public abstract class Action {
//abstract,只有方法的名字,没有方法的实现
public abstract void doSomething();
}
package com.OOP.Demo08;
//子类继承抽象类则必须实现抽象类的抽象方法,除非子类也是抽象类
public class A extends Action{
@Override
public void doSomething() {
}
}
抽象类的特点
- 不能new这个抽象类,只能靠子类去实现它
- 抽象类中可以写普通方法
- 抽象方法必须在抽象类里
- 抽象的抽象:约束
思考:抽象类存在构造器吗?
- 存在构造器
抽象类存在的意义
- 提高开发效率
接口的定义与实现(interface)
**接口:**只有规范!自己无法写方法,只能写约束,约束和实现分离:面向接口编程
接口就是规范,接口的本质是契约
接口的作用
- 接口定义一些约束,自己不能实现
- 接口定义一些方法,可以让让不同人实现
- 接口定义的方法默认用public abstract修饰
- 接口只能定义常量,默认修饰public static final
- 接口不能被实例化
- implement可以实现多个接口,变相的实现多继承
- 必需重写接口中的方法
内部类
内部类就是在一个类的内部再定义一个类,则成为内部类,原本的类成为外部类
package com.OOP.Demo10;
public class Outer {
private int id=10;
public void out(){
System.out.println("这是一个外部类");
}
public class Inner{
//内部类可以获得外部类的私有属性
public void in(){
System.out.println(
"这是一个内部类"
);
}
public void getId(){
System.out.println(id);
}
}
//静态内部类
public static class Inner2{
//内部类可以获得外部类的私有属性
public void in(){
System.out.println(
"这是一个静态内部类"
);
}
}
public void method(){
class Inner{
public void in(){
}
}
}
}
//一个java类中可以有多个class,但是只能有一个public class
class A{
}
package com.OOP.Demo10;
public class Test {
public static void main(String[] args) {
//没有名字初始化类,不用将示例保存到变量中
new Apple().eat();;
new UserService(){
};
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserService{
}
package com.OOP;
import com.OOP.Demo10.Outer;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过这个外部类来实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
}
}
异常
什么是异常?
软件程序在运行的过程中,非常可能遇到一些异常的问题,我们统称为异常:Exception
package com.exception;
public class Demo01 {
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
demo01.a();
}
public void a(){
b();
}
public void b(){
a();
}
}
/*
Exception in thread "main" java.lang.StackOverflowError
*/
简单分类
- 检查性异常
- 运行时异常
- 错误ERROR
异常体系结构
Error
Error类有对象由java虚拟机生成并抛出,大多数错误与代码编写者执行的操作无关
Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMenoryError.这些异常发生时,java虚拟机一般会终止线程
Exception
Exception分支中有一个重要的子类RuntimeException(运行时异常)
ArrayIndexOutBoundsException(数组下标越界)
NullPointException(空指针异常)
ArithmeticException(算数异常)
MissingResourceException(丢失资源)
ClassNotFoundException(找不到类)
这些异常是由程序逻辑醋无引起的,程序应该从逻辑角度避免这些异常
Error通常是灾难性的致命错误,Exception通常可以被程序处理,并且在程序中应该尽可能的区处理这些异常
捕获和抛出异常
一场梳理的五个关键字
- try
- catch
- finally
- throw
- throws
package com.exception;
public class Test {
public static void main(String[] args) {
int a=1;
int b=0;
//java支持捕获多个异常,但一旦被捕获就不再执行下面的catch,只会执行一个
try {//try监控区域
if(b==0){
//主动抛出异常 throw 一般在方法中使用,假设这个方法中处理不了这个异常,方法上抛出异常throws
throw new ArithmeticRxception();
}
System.out.println(a/b);
}catch (ArithmeticException e){//catch(想要捕获的异常类型)捕获异常
System.out.println("程序出现异常,变量b不能为0");
}catch (ArithmeticException e){//catch(想要捕获的异常类型)捕获异常
System.out.println("程序出现异常,变量b不能为0");
}catch (ArithmeticException e){//catch(想要捕获的异常类型)捕获异常
System.out.println("程序出现异常,变量b不能为0");
}finally {
//处理善后工作,无论是否出异常,这里的代码一定被执行
System.out.println("finally");
}
}
}
/*
程序出现异常,变量b不能为0
finally
*/
自定义异常
自定义异常,只需要继承Exception类即可