多态
定义:编译时类型和运行时类型不一致,此时产生多态。
格式:
编译时类型 对象名 = new 运行时类型();
多态只有对象多态和方法多态,属性没有多态。
子类对象赋值给父类对象就是向上转型
父类对象赋值给子类对象就是向下转型,向下转型有风险。
向上转型和向下转型统称为造型
package com.wlx.day75;
public class Animal
{
String cname;
public void eat(String food)
{
System.out.println("Animal 吃"+food);
}
public String say()
{
System.out.println("cname======"+cname);
return cname;
}
}
package com.wlx.day75;
public class Cat extends Animal
{
//所有引用数据类型的默认值都是null
String cname;
@Override
public void eat(String food)
{
System.out.println(cname+"猫在吃"+food);
}
public void catEat(String food)
{
System.out.println(cname+"在吃"+food);
}
public static void main(String[] args)
{
//数据类型 数据类型
//编译时类型 运行时类型
Cat cat = new Cat();//此处的cat没有多态
//cat.cname = "加菲猫";
//cat.catEat("鱼");
//数据类型 数据类型
//编译时类型 运行时类型
Animal ct = new Cat();//此处的ct为多态对象
//该cname属性没有多态,编译时和运行时调用都是Animal中的cname属性
ct.cname = "机器猫";
System.out.println("cname---"+ct.cname);
//此处的eat()方法编译时调用的是Animal类中的eat()方法,运行时调用的是Cat类中的eat()方法
ct.eat("猫粮");
ct.say();
}
}
instanceof
使用instanceof可以避免在引用数据类型转换时的类型转换异常。
格式:
对象名 instanceof 类名/接口名
作用:判断某个对象是否可以转换成指定的类/子类/接口的类型,如果是,则结果为true,可以转换,否则不可以转换。
package com.wlx.day75;
public class Dog extends Animal
{
public static void main(String[] args) {
Dog dog = new Dog();
//向上
Animal dg = new Dog();
//查看dg是否是Dog的实例对象
System.out.println("dog---"+(dg instanceof Dog));
Animal eh = new EhDog();
//查看dg是否是Dog的子类的实例对象
System.out.println(eh instanceof Dog);
//向下转型
Dog dog1 = (Dog)dg;
//向上转型
Animal a = new Cat();
//Dog dog2 = (Dog)a;
// System.out.println(a instanceof Cat);
//如果a对象是Dog的实例对象或子类实例对象,结果为true
if(a instanceof Dog)
{
//就可以将a转换成Dog对象
Dog dog2 = (Dog)a;
}
}
}
包装类
自动装箱:
将基本数据类型的数据或变量直接赋值给对应包装类型的对象或Object的过程就是自动装箱。
自动拆箱:
将包装类对象直接赋值给对应基本数据类型的变量的过程就是自动拆箱。
package com.wlx.day75;
public class Demo
{
public static void main(String[] args)
{
int a = 12;
//装箱,这种方式已过时,废除了
// Integer it = new Integer(a);
//自动装箱
Integer it = a;
//自动拆箱
int aa = it;
boolean b = true;
//装箱,这种方式已过时,废除了
// Boolean bl = new Boolean(b);
//自动装箱
Boolean bl = b;
//自动拆箱
boolean bb = bl;
//自动装箱
Object obj = 123;
Object ob = aa;
//123处理成字符串
int abc = 123;
String s = String.valueOf(abc);
//将字符串123处理成int类型
//拆箱
int cba = Integer.parseInt(s);
}
}
异常
1.1、概念
异常Exception的父类Throwable,Throwable还有一个子类是Error。
Exception:主要就是程序员需要处理的,而且能够处理的程序代码异常。
Error:主要是硬件以及程序员无法处理的代码异常。
Exception分为:
编译时异常:
编写代码完成以后,出现的异常就是编译时异常。
运行时异常:
运行代码时才会出现的Exception异常,都是运行时异常,都是RuntimeException的子类,除此以外都是编译时异常。
1.2、处理异常机制
1.2.1、try{}catch()
格式一:
格式:
try
{
有异常的代码
}
catch(异常对象)
{
处理异常代码
}
…
catch(异常对象)
{
处理异常代码
}
备注:当有多个catch语句时,按照从小到大的顺序排列。
package com.wlx.day75;
public class ExceptionDemo
{
public static void main(String[] args) {
try
{
int a = 6;
int b = 0;
int c = a/b;
}catch (ArithmeticException e)
{
// System.out.println("不能除以0");
//开发阶段此处应该打印异常跟踪栈信息
e.printStackTrace();
//开发完成以后交付给客户时,要么弹窗/打印日志信息/要么跳转页面。
// JOptionPane.showMessageDialog(null,"不能除以0");
}
}
}
格式二:
try
{
有异常的代码
}
catch(异常对象1|…|异常对象N)
{
处理异常代码
}
备注:这些异常对象都是并列的关系,不能有大小关系。
package com.wlx.day75;
public class ExceptionDemo2
{
public static void main(String[] args)
{
try {
int[] a = new int[]{12,22,26};
System.out.println(a[3]);
}
catch (ArrayIndexOutOfBoundsException|ArithmeticException|NullPointerException e)
{
System.out.println("数组下标越界了");
}
}
}
格式三:
try
{
有异常的代码
}
catch(异常对象)
{
处理异常代码
}
finally
{
回收资源
必须执行的代码
不要在finally中返回数据,会覆盖原有返回的数据
}
try
{
有异常的代码
}
finally
{
回收资源
必须执行的代码
不要在finally中返回数据,会覆盖原有返回的数据
}
备注:finally不能单独使用,必须要和try{}或try{}catch(){}一起使用。
package com.wlx.day75;
public class ExceptionDemo2
{
public int add(int a,int b)
{
int c = 0;
try {
c = a + b;
return c;
} catch (Exception e) {
e.printStackTrace();
} finally {
//此处代码一直被执行,会将上面的return c的结果覆盖掉/替换掉。
return 123;
}
// return c;
}
public int mul(int a,int b)
{
int c = 0;
try {
c = a * b;
return c;
} finally {
//此处代码一直被执行,会将上面的return c的结果覆盖掉/替换掉。
//return 678;
}
}
public static void main(String[] args)
{
/* try {
int[] a = new int[]{12,22,26};
System.out.println(a[3]);
}
catch (ArrayIndexOutOfBoundsException|ArithmeticException|NullPointerException e)
{
System.out.println("数组下标越界了");
}*/
// int num = new ExceptionDemo2().add(3,3);
ExceptionDemo2 ed = new ExceptionDemo2();
int num = ed.add(223,32);
System.out.println(num);
System.out.println(ed.mul(3, 6));
}
}
1.2.2、throws
抛出异常:
格式:
public void 方法名()throws 异常类1,…,异常类N
{
}
备注:当一个方法中出现异常以后,不适合或不能在该方法中处理该异常时,使用throws继续往外抛出异常,但是推荐最终一定要在main函数中将异常处理掉,如果继续往外抛出异常,此时就会将异常抛给JVM,如果JVM能够处理该异常,则可以正常处理调用,否则正常继续抛出异常。
package com.wlx.day75;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ThrowsDemo
{
public void method()throws IOException, FileNotFoundException
{
int a = 6;
int b = 0;
int c = a/b;
}
/**
* 如果在main方法中继续往外抛出异常,此时就会将异常抛给JVM
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
new ThrowsDemo().method();
}
}
1.2.3、throw
throw抛出的是异常对象,当抛出的异常对象是编译时异常时,必须要和try{}catch{}或throws一起使用,当抛出的异常对象是运行时异常时,该throw可以单独使用。
格式:
throw new Exception();
package com.wlx.day75;
import java.io.IOException;
public class ThrowDemo
{
public void demo()
{
//抛出运行时异常对象,此时可以单独使用throw
throw new RuntimeException();
}
/**
* 由于该方法中抛出的异常是编译时异常,因此throw不能单独使用,
* 必须要和throws或try{}catch{}一起使用
*/
public void test()//throws IOException
{
try {
throw new IOException();
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.3、自定义异常
编写自定义异常时,可以编写编译时自定义异常,也可以编写运行时自定义异常,当编写编译时异常时,继承Exception,当编写运行时异常,继承RuntimeException,进而根据自己的需要/需求编写一些方法即可。
备注:自定义异常在命名时,最后以Exception结尾。
package com.wlx.day75;
/**
* 自定义运行时异常
*/
public class MyException2 extends RuntimeException
{
public MyException2(String message)
{
super(message);
}
public static void main(String[] args)
{
throw new MyException2("zdyException");
}
}