09什么是多态
即同一方法可以根据发送对象的不同而采取多种不同的行为方法(但最后运行结果唯一)
我理解就是一个自己类型指向其它类型的对象调用了某个同名方法之后的结果不容易弄清楚
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(一般是父类指向子类) Father f = new Son();
存在条件:
- 有继承关系
- 子类重写了父类的方法
- 父类引用指向子类对象
对象能执行哪些方法主要看定义对象时左边的类型,所以父类指向子类的对象不能调用子类中独有的方法,但可以被强制转化成子类的对象后可以调用
eg:Father f = new Son();
//say()是子类中的方法,如果f不强制转换为子类对象的话就无法调用say()
((Son) f).say();
注意:多态是方法的多态,而且static、final、private修饰的方法不能用多态。属性没有多态性
//类型转换异常错误是ClassCastException
instance of 和类型转换
instance of 可以判断两个类是否存在父子关系
结合代码看更直观:
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object s1 = new Student();
System.out.println(s1 instanceof Student); //true
System.out.println(s1 instanceof Person); //true
System.out.println(s1 instanceof Object); //true
System.out.println(s1 instanceof Teacher); //false
System.out.println(s1 instanceof String); //false
System.out.println("=========================");
Person s2 = new Student();
System.out.println(s2 instanceof Student); //true
System.out.println(s2 instanceof Person); //true
System.out.println(s2 instanceof Object); //true
System.out.println(s2 instanceof Teacher); //false
//编译不通过,因为这俩同级 System.out.println(s2 instanceof String);
System.out.println("=========================");
Student s3 = new Student();
System.out.println(s3 instanceof Student); //true
System.out.println(s3 instanceof Person); //true
System.out.println(s3 instanceof Object); //true
父子类型的转换:
子类转为父类,向上转型,无需强制转换,但会丢失子类本身独有的方法
父类转为子类,向下转型,需要强制转换
10 static关键字详解
变量:
private static int age; //静态的变量,可以直接用类名调用,因此也叫类变量
private double score; //非静态的变量,不能用类名调用
代码块:
public class static_ {
private static int age;
private double score;
public static void main(String[] args) {
new static_();
System.out.println("================");
new static_();
}
//代码块
// 2
{
System.out.println("匿名代码块");
}
// 1 但只能运行一次
static{
System.out.println("静态代码块");
}
// 3
public static_(){
System.out.println("构造方法");
}
}
匿名代码块一般用来赋初值
静态代码块最先出来,但只执行一次
静态导入包:
import static java.lang.Math.random;
public class static_ {
public static void main(String[] args) {
System.out.println(random());
//本来括号里是要写Math.random()的,但是有了静态导入就不需要了
}
额外:final修饰的类不能被继承
11抽象类
<非重点>
关键字:abstract 可以用来修饰方法也可以用来修饰类,如果修饰方法那么该方法就是抽象方法,如果修饰类那么该方法就是抽象类
抽象类中可以没有抽象方法,(抽象类中的方法也可以是普通方法),但是有抽象方法的类一定要声明为抽象类
抽象类:不能使用new关键字来创建对象,它是用来让子类继承的
抽象方法:只有方法的声明,没有方法的实现,(连中括号都没有,而且结束时要加上分号)它是用来让子类实现的
子类继承抽象类就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类
抽象类的构造方法不能直接调用,因为抽象类不能实现实例。但是一旦一个普通类继承了抽象类,便也可以在构造函数中调用其抽象类的构造函数,也可以使用其方法
12接口的定义与实现
声明类的关键字是class,声明接口的关键字是interface
区别:
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有
- 接口:只有规范,自己无法写方法(约束,我是专业的~)
接口里的规范必须要有类实现,实现它们的类用关键字implements连接该接口名,多个接口之间用逗号隔开(实现了伪多继承)
接口里定义的属性都是静态常量(public static final),方法都是抽象的(public abstract)
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想,如果你是天使,则必须能飞;如果你是汽车,则必须能跑;如果你好人,则必须干掉坏人;如果你是坏人,则必须欺负好人。
接口的本质是契约,就像我们人间的法律一样,制定好后大家都遵守。
OOP的精髓是对对象的抽象,最能体现这一点的就是接口
接口不能被实例化,没有构造方法
13N种内部类
内部类就是在一个类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了
-
成员内部类
public class chengYuanNBL { private int id = 75; public void say(){ System.out.println("我是外部类的方法"); } class inner{ public void ssay(){ System.out.println("我是内部类的方法"); } //可以获得外部类的私有属性 public void getid(){ System.out.println(id); } } } class shixian{ public static void main(String[] args) { chengYuanNBL a = new chengYuanNBL(); //内部类的实例化有点复杂(a.new inner();) chengYuanNBL.inner b = a.new inner(); b.ssay(); b.getid(); } }
-
静态内部类
public class jingTaiNBL { private int id = 97; public int bl = 0; public void say(){ System.out.println("测你艾木"); } public static class inner{ public void ungetid(){ //会报错,静态内部类不能获取外部类的属性System.out.println(id); //公有的属性也不行,任何属性都不行System.out.println(bl); } } }
-
局部内部类
public class jvBuNBL { public void method(){ //类似于局部变量 class inner{ } } }
-
匿名内部类
实例化的时候不设置名字
public class niMingNBL { public static void main(String[] args) { new Apple().eat(); } } class Apple{ public void eat(){ System.out.println("我爱吃苹果!"); } }