3.面向对象
3.1多态
1介绍:基本数据类型的类型转换 == 引用类型的类型提升
2多态: 一种事物的多种形态|多种表现形式
3多态的最终体现:
父类的引用指向子类的对象
4 多态的前提:
继承|实现
5 多态的优点: 多态可以让程序变得更加灵活,便于后期维护
public class polymorphismDemo01 {
public static void main(String[] args) {
//对应类型的数据赋值给对应类型的变量
Person p = new Person();
Student s = new Student();
//多态 父类引用指向子类对象
Person p2 = new Student();
System.out.println(s);
test(new Student());
}
static void test(Person s){ //Person s = new Student();
}
}
class Person{}
class Student extends Person{}
6多态的使用:
当父类类型的引用调用成员时候:
成员变量:
编译运行看父类|左边|类型
成员方法:
编译看父类|类型|左边
运行找子类|对象|右边
7当通过父类的引用调用成员方法时候,如果子类有重写方法就调用重写的,如果没有找父类
8如果多态不配合方法的重写,多态也没有意义
public class polymorphismDemo02 {
public static void main(String[] args) {
//多态
Fu fu = new Zi();
//System.out.println(fu.name);
//fu.test();
}
}
class Fu{
//String name = "Fu";
/*void test(){
System.out.println("父类test");
}*/
}
class Zi extends Fu{
//String name = "Zi";
//@Override
void test(){
System.out.println("子类test");
}
}
*1.向上转型 : 自动类型提升
从小到大->从子类到父类
父类类型 引用 = new 子类类型();
long l = 1;
//向上转型-->化妆
KongZiDie die = new KongZi();
die.teach();
*2.向下转型 : 强制类型转换
从大到小 ->从父类到子类
小范围类型 变量 = (小范围类型)大范围类型的数据;
int i = (int)l;
- 向下转型可能遇到类型转换异常ClassCastException:
引用 instanceof 类型
判断前面的引用是否指向后面类型的对象,或者是否指向后面类型子类的对象,如果是返回true,不是返回false
//转型之前的判断: 为了预防类型转换异常的出现
if(die instanceof KongZi){
}else{
}
//向下转型->卸妆
KongZi zi = (KongZi)die;
注意:
多态引用不能调用子类中独有的方法,对子类新增功能不可见
如果想要调用子类的独有方法,需要向下转型
如果向下转型想要保证不出现类型转换异常,可以使用instanceof进行提前判断
3.1.1完整代码
public class CastDemo01 {
public static void main(String[] args) {
//向上转型-->化妆
KongZiDie die = new KongZiBrother();
die.teach();
//转型之前的判断: 为了预防类型转换异常的出现
if(die instanceof KongZiBrother){
//向下转型->卸妆
KongZiBrother zi = (KongZiBrother)die;
//KongZiBrother zi = new KongZi();
zi.play();
zi.teach();
}else{
KongZi zi = (KongZi)die;
zi.play();
zi.teach();
}
System.out.println(die instanceof KongZi); //false
System.out.println(die instanceof KongZiBrother); //true
System.out.println(die instanceof KongZiDie); //true
}
}
//父类
class KongZiDie{
String name = "kongzidie";
void teach(){
System.out.println("敲代码...");
}
}
//子类
class KongZi extends KongZiDie{
String name = "kongzi";
void teach(){
System.out.println("论语...");
}
void play(){
System.out.println("LoL...");
}
}
class KongZiBrother extends KongZiDie{
String name = "KongZiBrother";
void teach(){
System.out.println("圣经");
}
void play(){
System.out.println("绝地求生!!!...");
}
}
3.2 重写 与 重载之间的区别
相同点:
都是方法的特性
不同点:
1.重载:
同一个类中的多个方法
方法名相同
参数列表不同|方法签名不同
2.重写: 重写定义方法体
不同的两个类
继承关系|实现关系
方法签名相同(方法名+参数列表)
3.2.1重写的使用
-
场景:
在子类继承父类后,继承了一写功能方法,有些功能,功能的实现不满意,可以进行功能的重写(重新实现) -
使用:
子类一旦重写方法,子类对象调用的时候,就会发生就近原则
子类对象调用功能时候,子类存在找子类,子类没有找父类 -
检查是否为重写方法:
1.@Override 强制检查是否为重写方法,不是报错
2.工具中方法的左侧有提示
class JianLin extends YeYe{
public String name = "王健林";
//名言
static JianLin words(){
System.out.println("先定一个小目标,挣它一个亿!!!");
return null;
}
public void life(){
System.out.println("进口矿泉水洗脚!!!!");
}
//重写
public void test(){
System.out.println("JianLin类功能test");
}
}
//子类
class SiCong extends JianLin{
public String name = "王思聪";
//名言 重写
public static SiCong words(){
System.out.println("我不在乎....!!!");
return null;
}
}
注意:
子类一旦重写父类中的方法,就是对父类方法进行屏蔽
3.2.2 重写条件(了解)
-
== <= >=满足的条件:
== : 方法签名完全相等
<= : 返回值类型为基本数据类型要求完全相等,如果为引用数据类型,子类方法返回值类型<=父类方法的返回值类型
>= : 权限修饰符: 子类方法的权限修饰符>=父类方法的权限修饰符 -
不能被重写的方法:
1.被private关键字修饰的方法不能被重写
1.被final关键字修饰的方法不能被重写
1.被static关键字修饰的方法不能被重写
当子类中出现于父类静态方法同名的方法时候,子类的同名方法也要是静态的,否则报错,但是不是重写方法
3.3 Object 老祖宗类
Object介绍:
java中所有类的父类
java中的所有类都会直接|间接的继承自Object类
如果没有显示的继承自某个类型,默认会继承Object
ctrl+n->查询某个类
3.3.1 equals方法
**equals介绍:**equals 比较两个对象是否相等(默认使用==比较,比较对象地址)
如果想要实现比较对象内容,而非地址值,需要在子类中重写equals方法,需要自己实现比较内容(成员属性的值)
public boolean equals(Object obj) {
return (this == obj);
}
3.3.2 equals 完整代码
public class ObjectDemo01 {
public static void main(String[] args) {
Fu fu = new Fu();
Fu fu2 = fu;
System.out.println(fu == fu2); //true
System.out.println(fu.equals(fu2)); //true
String str1 = "zhangsan";
String str2 = "zhangsan";
System.out.println(str1.equals(str2));
Person p1 = new Person("yinwei",20,1001);
Person p2 = new Person("yinwei2hao",30,1001);
//比较引用数据类型: 比较两个对象的地址是否相等
System.out.println(p1 == p2); //比较地址 false
//比较基本数据类型: 比较数据值
System.out.println(p1.equals(p2)); //比较内容 true
System.out.println(p1.equals(new String())); //比较地址 false
}
}
class Fu{}
class Zi extends Fu{}
注意:通过java实现功能就是为了处理生活中的业务,会以生活中具体的逻辑考虑问题:
1.认为两个对象,如果所有成员属性的值都想等,就应该是一个对象
-
在java中只要通过new关键字创建的对象,无论成员属性值是否相等,地址都不相等,如果比较地址,都不相等,所以引用数据类型对象的时候,不让它默认比较地址,手动让她比较内容
3.4 抽象
abstract 抽象的
抽象类: abstract修饰的类
抽象方法: 被abstract修饰的方法
可以没有方法体
必须存在与抽象类中开发部门Develop: 工作work()
//父类 public abstract class Develop { //工作 方法体不确定些什么,不确定怎么写,那就不写 public abstract void work1(); public abstract void work2(); //普通方法 public void sleep(){ System.out.println("边工作边休息..."); } }
攻城狮java:工作work()
/*
子类
java攻城狮
普通的子类|具体的子类(没有被abstract修饰的类)
*/
public class Java extends Develop{
//对父类中继承的抽象方法进行重写实现
@Override
public void work1() {
System.out.println("JAVA按照规矩办事!!!");
}
@Override
public void work2() {
System.out.println("JAVA做后端开发...");
}
//形象 -->新增方法
public void xingxiang(){
System.out.println("没头发了!!!!又该植发了!!!!!");
}
}
注意:
1.抽象类不能够实例化
2.抽象方法必须存在抽象类中
3.抽象类中可以存在抽象方法,可以存在普通的具体方法,可以存在成员,构造器…
4.抽象方法必须要被重写才能使用
5.抽象方法只要被重写就可以使用,不需要再次重写,可以根据需求进行重写
6.抽象类使用: 通过具体子类的对象调用
*1.普通的子类: 需要重写所有抽象方法+按需新增
*2.抽象子类: 按需重写抽象方法+按需新增
7.abstract不能与private,static,final,native同时存在