多态
多态的概述,多态的形式
什么是多态? 同类型的对象,执行同一个行为,会表现出不同的行为特征 多态的常见形式 多态中成员访问特点 ○ 方法调用:编译看左边,运行看右边
class Animal {
public void run ( ) {
System . out. println ( "动物跑~" ) ;
}
}
class Dog extends Animal {
public void run ( ) {
System . out. println ( "狗跑~" ) ;
}
}
class Tortoise extends Animal {
public void run ( ) {
System . out. println ( "乌龟跑~" ) ;
}
}
public class Test1 {
public static void main ( String [ ] args) {
Animal animal = new Dog ( ) ;
animal. run ( ) ;
Animal animal1 = new Tortoise ( ) ;
animal1. run ( ) ;
}
}
○ 变量调用:编译看左边,运行也看左边(多态侧重行为多态 )
class SportMan {
public String name = "运动员" ;
}
class Swimmer extends SportMan {
public String name = "游泳运动员" ;
}
class BasketballPlayer extends SportMan {
public String name = "篮球运动员" ;
}
public class Test2 {
public static void main ( String [ ] args) {
SportMan sportMan = new Swimmer ( ) ;
System . out. println ( sportMan. name) ;
SportMan sportMan1 = new BasketballPlayer ( ) ;
System . out. println ( sportMan1. name) ;
}
}
多态的前提 ○ 有继承/实现类;有父类引用指向子类对象;有方法重写
多态的优缺点
class Animal {
public void run ( ) {
System . out. println ( "动物跑~" ) ;
}
}
class Dog extends Animal {
public void bark ( ) {
System . out. println ( "狗在吠~" ) ;
}
}
class Cat extends Animal {
public void sheep ( ) {
System . out. println ( "猫在睡~" ) ;
}
}
public class Test {
public static void main ( String [ ] args) {
Animal animal = new Dog ( ) ;
Animal animal1 = new Cat ( ) ;
}
}
多态下引用数据类型的类型转换
自动类型转换(从子到父): 子类对象赋值给父类类型的变量指向强制类型转换(从父到子)
此时必须进行强制类型转换;子类 对象变量 = (子类)父类类型的变量 作用;可以解决多态下的劣势,可以实现调用子类独有的功能 注意:如果转型后的类型 和对象真实类型不是同一种类型 ,那么在转换的时候就会出现ClassCastException
class Animal {
public void run ( ) {
System . out. println ( "动物跑~" ) ;
}
}
class Dog extends Animal {
public void bark ( ) {
System . out. println ( "狗在吠~" ) ;
}
}
class Cat extends Animal {
public void sheep ( ) {
System . out. println ( "猫在睡~" ) ;
}
}
public class Test {
public static void main ( String [ ] args) {
Animal animal = new Dog ( ) ;
Dog dog = ( Dog ) animal;
dog. bark ( ) ;
( ( Dog ) animal) . bark ( ) ;
}
}
3.Java建议强转换前使用instanceof判断当前对象的真实类型,再进行强制转换
格式:变量名 instanceof 真实类型 用法:判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其他子类类型,是则返回true,反之。
class Animal {
public void run ( ) {
System . out. println ( "动物跑~" ) ;
}
}
class Dog extends Animal {
public void run ( ) {
System . out. println ( "狗跑~" ) ;
}
}
class Cat extends Animal {
public void run ( ) {
System . out. println ( "猫跑~" ) ;
}
}
public class Test {
public static void main ( String [ ] args) {
Animal animal = new Cat ( ) ;
if ( animal instanceof Cat ) {
System . out. println ( "猫类对象" ) ;
} else if ( animal instanceof Dog ) {
System . out. println ( "狗类对象" ) ;
}
}
}
多态综合案例
使用面向对象编程模拟:设计一个电脑对象,可以安装2个USB设备 鼠标:被安装时可以完成接入、调用点击功能、拔出功能 键盘:被安装时可以完成接入、调用打字功能、拔出功能
interface USB {
void connect ( ) ;
void unconnect ( ) ;
}
class Mouse implements USB {
private String name;
public Mouse ( String name) {
this . name = name;
}
@Override
public void connect ( ) {
System . out. println ( name + "已成功接入" ) ;
}
@Override
public void unconnect ( ) {
System . out. println ( name + "已成功弹出" ) ;
}
public void click ( ) {
System . out. println ( name + "被点击了" ) ;
}
}
class keyBoard implements USB {
private String name;
public keyBoard ( String name) {
this . name = name;
}
@Override
public void connect ( ) {
System . out. println ( name + "已成功接入" ) ;
}
@Override
public void unconnect ( ) {
System . out. println ( name + "已成功弹出" ) ;
}
public void input ( ) {
System . out. println ( name + "成功输入" ) ;
}
}
class Computer {
public void install ( USB usb) {
usb. connect ( ) ;
if ( usb instanceof Mouse ) {
( ( Mouse ) usb) . click ( ) ;
} else if ( usb instanceof keyBoard) {
( ( keyBoard) usb) . input ( ) ;
}
usb. unconnect ( ) ;
}
}
public class Test {
public static void main ( String [ ] args) {
Computer computer = new Computer ( ) ;
USB usb = new Mouse ( "惠普鼠标" ) ;
computer. install ( usb) ;
System . out. println ( "--------------------" ) ;
USB usb1 = new keyBoard ( "惠普键盘" ) ;
computer. install ( usb1) ;
}
}
内部类
内部类概述
内部类就是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解成(宿主) - 内部类的使用场景、作用
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构可以选择使用内部类来设计 内部类通常可以方便访问外部类的成员,包括私有的成员 内部类提供更好的封装性,内部类本身就可以用private protected等修饰,封装性可以做更多控制
内部类之一:静态内部类[了解]
什么是静态内部类?
有static修饰,属于外部类本身 它的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别人里面而已
静态内部类创建对象的格式:
class Outer {
public static class Inner {
private int onlineNumber = 30 ;
private String name = "张三" ;
public void show ( ) {
System . out. println ( "静态成员内部类" ) ;
}
public Inner ( ) {
}
public Inner ( int onlineNumber, String name) {
this . onlineNumber = onlineNumber;
this . name = name;
}
public int getOnlineNumber ( ) {
return onlineNumber;
}
public void setOnlineNumber ( int onlineNumber) {
this . onlineNumber = onlineNumber;
}
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
}
}
public class Test {
public static void main ( String [ ] args) {
Outer. Inner inner = new Outer. Inner ( ) ;
System . out. println ( inner. getName ( ) ) ;
System . out. println ( inner. getOnlineNumber ( ) ) ;
inner. show ( ) ;
}
}
静态内部类的访问拓展:
静态内部类中可以直接访问外部类的静态成员,外部类的静态成员只有一份可以被共享访问 静态内部类中不可以直接访问外部类的实例成员,外部类的实例成员必须用外部类对象访问
内部类之二:成员内部类[了解]
什么是成员内部类?
无static修饰,属于外部类的对象 JDK16之前,成员内部类中不能定义静态成员变量,JDK16开始可以定义静态成员
成员内部类创建对象的格式:
public class Outer {
public String name = "张三" ;
public String schoolName = "蓝翔技术专修学院" ;
public class Inner {
public static int num = 0 ;
public void show ( ) {
System . out. println ( "姓名:" + name + "\t" + "学校:" + schoolName) ;
}
}
}
class Test {
public static void main ( String [ ] args) {
Outer. Inner inner = new Outer ( ) . new Inner ( ) ;
inner. show ( ) ;
}
}
成员内部类的访问拓展:
成员内部类中可以直接访问外部类的静态成员,外部类的静态成员只有一份可以被共享访问 成员内部类的实例方法中可以直接访问外部类的实例成员,因为必须先有外部类对象,才能有成员内部类对象,所有可以直接访问外部类对象的实例成员
成员内部类-面试题
请观察如下代码,写出合适的代码对应其注释要求输出结果
public class People {
private int heartbeat = 150 ;
public class Heart {
private int heartbeat = 110 ;
public void show ( ) {
int heartbeat = 70 ;
System . out. println ( heartbeat) ;
System . out. println ( this . heartbeat) ;
System . out. println ( People . this . heartbeat) ;
}
}
}
class Test1 {
public static void main ( String [ ] args) {
People. Heart heart = new People ( ) . new Heart ( ) ;
heart. show ( ) ;
}
}
注意:在成员内部类中访问所在外部类对象,格式:外部类名.this
内部类之三:局部内部类[了解]
局部内部类放在方法、代码块、构造器等执行体中 局部内部类的类文件名为:外部类$N内部类.class
内部类之四:匿名内部类概述[重点]
匿名内部类:
本质上是一个没有名字的1局部内部类,定义在方法中、代码块中、等 作用 :方便创建子类对象,最终目的为了简化代码编写
格式: 特点总结:
匿名内部类是一个没有名字的内部类 匿名内部类写出来就会产生一个匿名内部类的对象 匿名内部类的对象类型相当于是当前new的那个的类型的子类类型
public abstract class Animal {
public abstract void run ( ) ;
}
class Test {
public static void main ( String [ ] args) {
Animal animal = new Animal ( ) {
@Override
public void run ( ) {
System . out. println ( "老虎跑得很快~" ) ;
}
} ;
animal. run ( ) ;
}
}
匿名内部类常见使用形式
public class Test2 {
public static void main ( String [ ] args) {
go ( new Swimming ( ) {
@Override
public void swim ( ) {
System . out. println ( "运动员跑得很快~" ) ;
}
} ) ;
}
public static void go ( Swimming swimming) {
System . out. println ( "开始~" ) ;
swimming. swim ( ) ;
System . out. println ( "结束~" ) ;
}
}
interface Swimming {
void swim ( ) ;
}
使用总结:匿名内部类可以作为方法的实际参数进行传输
匿名内部类真实使用场景演示
import javax. swing. * ;
import java. awt. event. ActionEvent ;
import java. awt. event. ActionListener ;
public class Test3 {
public static void main ( String [ ] args) {
JFrame win = new JFrame ( "登录界面" ) ;
JPanel panel = new JPanel ( ) ;
win. add ( panel) ;
JButton btn = new JButton ( "登录" ) ;
btn. addActionListener ( new ActionListener ( ) {
@Override
public void actionPerformed ( ActionEvent e) {
JOptionPane . showMessageDialog ( win, "点我一下,说明爱我!" ) ;
}
} ) ;
panel. add ( btn) ;
win. setSize ( 400 , 300 ) ;
win. setLocationRelativeTo ( null ) ;
win. setVisible ( true ) ;
}
}
常用API
什么是API?
API(Application Programming interface)应用程序编程接口 简单来说:就是Java帮我们已经写好的一些方法,我们直接拿过来用就可以了
Object
Object类的作用;
一个类要么默认继承了Object类,要么简介继承了Object类,Object类是Java中的祖宗类 Object类的方法是一切子类都可以直接使用的,所有我们要学习Object类的方法
toString方法
Object的toString方法:
方法名 说明 public String toString () 默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址
问题引出
开发中直接输出对象,默认输出对象的地址其实是毫无意义的 开发中输出对象变量,更多的时候是希望看到对象的内容数据而不是对象的地址信息
toString存在的意义
父类toString()方法存在的意义就是为了被子类重写,以便返回对象的内容信息,而不是地址信息!!
public class Test {
public static void main ( String [ ] args) {
Student student = new Student ( "张三" , "男" , "蓝翔技术专修专业" ) ;
System . out. println ( student) ;
}
}
class Student {
private String name;
private String sex;
private String major;
public Student ( ) {
}
public Student ( String name, String sex, String major) {
this . name = name;
this . sex = sex;
this . major = major;
}
@Override
public String toString ( ) {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", major='" + major + '\'' +
'}' ;
}
}
equals方法
Object的equals方法:
方法名 说明 public Boolean equals (Object o) 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false
问题思考
直接比较两个对象的地址是否相同完全可以用“==”代替equals
equals存在的意义
父类equals方法存在的意义就是为了被子类重写,以便子类自己来定制比较规则
○ 重写子类方法
@Override
public boolean equals ( Object o) {
if ( this == o) return true ;
if ( o == null || getClass ( ) != o. getClass ( ) ) return false ;
Student student = ( Student ) o;
return Objects . equals ( name, student. name) && Objects . equals ( sex, student. sex) && Objects . equals ( major, student. major) ;
}
○ 使用重写方法
public class Test2 {
public static void main ( String [ ] args) {
Student student1 = new Student ( "张三" , "男" , "蓝翔技术专修学院" ) ;
Student student2 = new Student ( "李四" , "男" , "五道口理工学院" ) ;
Student student3 = new Student ( "张三" , "男" , "蓝翔技术专修学院" ) ;
System . out. println ( student1. equals ( student2) ) ;
System . out. println ( student1. equals ( student3) ) ;
}
}
Objects
Objects概述
Objects类与Object还是继承关系,Object类是从JDK1.7开始之后才有的 Objects的equals方法比较的结果是一样的,但是更安全
Objects的常见方法:
方法名 说明 public static boolean equals (Object a, Object b) 比较两个对象的,底层会进行非空判断,从而可以避免空指针异常。再进行equals比较 public static boolean isNull (Object obj) 判断变量是否为null,为null返回true,反之
public class Test {
public static void main ( String [ ] args) {
String question = null ;
String answer = "略" ;
System . out. println ( Objects . equals ( question, answer) ) ;
}
}
import java. util. Objects ;
public class Test2 {
public static void main ( String [ ] args) {
String name = "张三" ;
String sex = null ;
System . out. println ( Objects . isNull ( name) ) ;
System . out. println ( Objects . isNull ( sex) ) ;
}
}
StringBuilder
StringBuilder概述
StringBuilder是一个可变的字符串类,我们可以把它看成是一个对象容器 作用:提高字符串的操作效率,如拼接、修改等
StringBuilder构造器
名称 说明 public StringBuilder() 创建一个空白的可变的字符串对象,不包含任何内容 public StringBuilder(String str) 创建一个指定字符串内容的可变字符串对象
StringBuilder常用方法
方法名称 说明 public StringBuilder append(任意类型) 添加数据并返回StringBuilder对象本身 public String reverse() 将对象的内容反转 public int length() 返回对象内容长度 public String toString() 通过toString()就可以实现把StringBuilder转换为String
public class Test {
public static void main ( String [ ] args) {
StringBuilder stringBuilder = new StringBuilder ( ) ;
System . out. println ( stringBuilder. append ( 123 ) . append ( "abc" ) . append ( "我爱你中国" ) ) ;
System . out. println ( stringBuilder. reverse ( ) ) ;
System . out. println ( stringBuilder. length ( ) ) ;
way ( stringBuilder. toString ( ) ) ;
StringBuilder stringBuilder1 = new StringBuilder ( "我爱你中国" ) ;
System . out. println ( stringBuilder1) ;
}
public static void way ( String s) {
System . out. println ( "ok" ) ;
}
}
Math
Math类
包含执行基本数字运算的方法,Math类没有提供公开的构造器 如何使用类中的成员呢?看类的成员是否都是静态的,如果是,通过类名就可以直接调用
Math类的常用方法
方法名 说明 public static int abs(int a) 获取参数绝对值 public static double ceil(double a) 向上取整 public static double floor(double a) 向下取整 public static int round(float a) 四舍五入 public static int max(int a,int b) 获取两个int值中的较大值 public static double pow(double a,double b) 返回a的b次幂的值 public static double random() 返回值为double的随机数,范围[0.0,1.0)
public class Test {
public static void main ( String [ ] args) {
System . out. println ( Math . abs ( - 2 ) ) ;
System . out. println ( Math . ceil ( 3.1 ) ) ;
System . out. println ( Math . floor ( 4.9 ) ) ;
System . out. println ( Math . round ( 3.4 ) ) ;
System . out. println ( Math . max ( 5 , 7 ) ) ;
System . out. println ( Math . pow ( 2 , 3 ) ) ;
System . out. println ( Math . random ( ) ) ;
}
}
System
System类概述
System的功能是通用的,都是直接用类名调用即可,所以System不能被实例化
System类的常用方法
方法名 说明 public static void exit(int status) 终止当前运行的Java虚拟机,非零表示异常终止 public static long curentTimeMillis() 返回当前系统的时间毫秒值形式 public static void arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数) 数组拷贝
blic class Test {
public static void main ( String [ ] args) {
System . out. println ( System . currentTimeMillis ( ) ) ;
int [ ] arr1 = { 10 , 20 , 30 , 40 , 50 , 60 , 70 } ;
int [ ] arr2 = new int [ 6 ] ;
System . arraycopy ( arr1, 3 , arr2, 2 , 3 ) ;
System . out. println ( Arrays . toString ( arr2) ) ;
}
}
BigDecimal
BigDecimal作用
使用步骤
创建对象BigDecimal封装浮点型数据(最好的方式是调用方法)
BigDecima常用API
方法名 说明 public BigDecimal add(BigDecimal b) 加法 public BigDecimal subtract(BigDecimal b) 减法 public BigDecimal multiply(BigDecimal b) 乘法 public BigDecimal divide(BigDecimal b) 除法 public BigDecimal divide(另一个BigDecimal对象,精确几位,舍入模式) 除法
import java. math. BigDecimal ;
import java. math. RoundingMode ;
public class Test {
public static void main ( String [ ] args) {
BigDecimal a = BigDecimal . valueOf ( 2.5 ) ;
BigDecimal b = BigDecimal . valueOf ( 3.25 ) ;
System . out. println ( a. add ( b) ) ;
System . out. println ( b. subtract ( a) ) ;
System . out. println ( a. multiply ( b) ) ;
BigDecimal c = BigDecimal . valueOf ( 5 ) ;
BigDecimal d = BigDecimal . valueOf ( 2 ) ;
System . out. println ( c. divide ( d) ) ;
BigDecimal e = BigDecimal . valueOf ( 10.0 ) ;
BigDecimal f = BigDecimal . valueOf ( 3.0 ) ;
System . out. println ( e. divide ( f, 2 , RoundingMode . HALF_DOWN ) ) ;
}
}