一、面向对象
1.多态
1.1概述
多态:父类引用指向子类对象
父类引用:使用父类声明的引用类型变量
指向:通过内存地址,可以找到谁
使用父类类型声明的变量,保存子类对象的引用
父类 -变量=new子类();
java中提供了两种多态形式
1 编译时多态
编译时多态是静态的,主要是指方法重载,他是根据不同的参数 来区分不同的方法
编译之后就会变成不同的方法,在运行时,就谈不上多态了,知识两个不同的方法而已。
2 运行时多态
运行时多态是动态的,主要是指绑定动态来实现,指子类实现父类的方法。
1.1.2优缺点
优点: 耦合度降低,拓展性增强,易维护。
缺点:丢失子类特有的属性
public static void main(String[] args ){
Sup sup=new Sup();
sup.m1();
// 因为对象是在运行时创建的,而编译时是没有对象的,所以只能看类型中是否有该属性
// sup.m2();
}
}
class Sup{
public void m1(){
}
}
class Sub extends Sup{
public void m2(){
}
}
1.1.3多态的几种形式
(1) 直接多态:父类 变量 =new 子类();
(2) 实参/形参:方法参数列表哦是父类类型,而调用方法时,传递的是子类对象
(3)返回值 :返回值类型是父类类型,返回的值是子类对象
public static void main(String[] args) {
m1(new Sup1());
m1(new Sub1());
int i=m3();
Sup1 sup1 = m2();
}
public static void m1(Sup1 sup1){
System.out.println(sup1);
}
public static void m1(Sup sup){
System.out.println(sup);
}
public static Sup1 m2(){
return new Sub1();
}
public static int m3(){
return 22;
}
1.1.4使用多态调用属性
使用多态调用:
父类没有,子类没有,调用不了
父类没有,子类有,调用不了,丢失了子类特有属性
父类有,子类没有,调用父类
父类和子类都有,除了成员方法执行子类(方法覆写) 其他都执行父类
如果子类有,父类也有的成员方法,就执行子类,反之,就执行父类,没有就报错
1.1.5 instanceeof
多态:又叫向上转型
父类到子类,又叫向下转型,必须得先向上转型,才能向下转型
instanceof 严格来说是java中的一个双目运算符,用来测试一个对象是否为一个类的实例,防止类型转换异常
public static void main(String[] args) {
Sup4 sup =new Sub4();
// 丢失子类特有的属性
// sup.m2();
// 想调用 就需要强制类型转换
Sub4 sub = (Sub4) sup;
sub.m2();
move(new Dog());
// Animal a =new Animal();
// Cat c = (Cat)a;
}
public static void move(Animal animal){
// 比如 动物有猫和狗
// 我们如果直接把类型转换为猫类型,那么如果客户传递了一个狗进来
// 强制转换为猫 就会报错
// Cat cat = (Cat) animal;
// cat.eat();
// 判断某个对象是否由某个类实例化而来的
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.eat();
}else{
animal.move();
}
}
}
class Sup4 {
public void m1(){
System.out.println("父类m1");
}
}
class Sub4 extends Sup4{
public void m1(){
System.out.print("子类m1");
}
public void m2(){
System.out.println("子类特有m2");
}
1.2 Object
1.2.1 概述
Object是所有类的祖类,也就意味着它里面的方法是所有类都有的。
1.2.2 方法
1.2.3 Equals
public boolean equals (Object obj){
renturn this==obj;
}
01.equals(02); this 是01,obj是02
equals方法的设计目的: 比较两个对象是否为同一个对象
而object中的equals方法,默认比较内存地址
==比较基本类型,比较值的大小,而比较引用类型,比较的是内存地址。两个对象的地址是肯定不同的
如果我们比较两个对象的内存地址,那么久没有任何价值
那么我们一定是用两个对象中的具体属性进行比较才有价值
object不知道我们需要比较的是什么,所以默认比较地址
当我们需要比较的时候,需要根据需求,进行equals方法重写即可
public class Equals_01_a {
public static void main(String[] args)throws Exception {
Student2 s1 = new Student2(1, "张三");
Student2 s2 = new Student2(1, "张三");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
}
class Student2{
int id;
String name;
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(obj instanceof Student2){
// 比较
Student2 s1=(Student2) obj;
if(this.name.equals(s1.name))
return true;
}
return false;
}
public Student2(int id,String name){
super();
this.id=id;
this.name=name;
}
}