多态的使用
public class Person {
public void run(){
System.out.println("父类的run");}
}
public class Student extends Person {
@Override
public void run() {
System.out.println("子类的run");
}
public void run1(){
System.out.println("子类独有的方法,父类没有");
}
}
public class Student extends Person {
@Override
public void run() {
System.out.println("子类的run");
}
public void run1(){
System.out.println("子类独有的方法,父类没有");
}
}
public class Application {
public static void main(String[] args) {
//一个类型的对象是确定的
//new student();
//new person();
//可以指向引用的类型就不确定了 :父类的引用指向了子类
//student能调用的方法都是自己的或者继承父类的方法
Student s1 = new Student();
//Person父类型 可以指向子类但不能调用子类独有的方法
Person s2 =new Student();
Object s3=new Student();
s1.run();//子类的run
//子类重写了父类的方法,执行了子类的方法
s2.run();//子类的run
//对象能执行的哪些方法 是和左边的类型有关,和右边关系不大
s1.run1();//子类独有的方法,父类没有
//s2.run1();父类调用不了
}
}
注意事项:
- 多态是方法的多态,属性没有多态。
- 父类和子类,有联系 类型转换异常!ClassCateException
- 存在的条件:继承关系,方法需要重写,父类引用指向子类对象 Father f=new Song();
- 这些方法都不能重写,所以用不了多态:
- static方法,属于类,它不属于实例
- final 常量;
- private方法;
instanceof的用法
public class Application {
public static void main(String[] args) {
//继承关系如下:
//Object>Person>Student
//Object>Person>Teacher
//Object>String
Object object=new Student();
//instanceof 它的作用是用来判断,instanceof 左边对象是否为instanceof 右边类的实例
//这里特别注意:object是对象 和Object不一样 这是类
System.out.println(object instanceof Student);//true
System.out.println(object instanceof Person);//true
System.out.println(object instanceof Object);//true
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
System.out.println("=============================");
//最关键的话在这:
//编译看左边:指的是Person person与person instanceof Student中 Person类和Student类是否存在包含关系 存在就是编译通过
//运行看右边:指的是new Student()与person instanceof Person中Student类和Person类是否存在包含关系 存在就是true
Person person=new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Object);//true
System.out.println(person instanceof Teacher);//false
// System.out.println(person instanceof String);编译器报错 Person类与String类不存在关系
System.out.println("=================================");
Student student=new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
//System.out.println(student instanceof Teacher);编译器报错
// System.out.println(student instanceof String);编译器报错
}
}
类型转换
public class Person {
public void run(){
System.out.println("父类run");
}
public class Student extends Person {
public void go(){
System.out.println("子类go");
}
}
public class Application {
public static void main(String[] args) {
//类型转换:父与子的关系
//父(高) 子(低)
Person obj=new Student();
//将obj这个对象转换为Student类型(本来是Person类型)我们就可以Student类型的方法
Student obj1 = (Student) obj;
obj1.go();//子类go
((Student)obj).go();//与上面语法一样 子类go
//子类转换为父类,可能会丢失自己本来的方法
Student student=new Student();
Person person=student;//低转高 把Student类型 转换为Person类型
// person.go();用不了子类的go方法了
}
}
(可能写错了上面的)
建议参考下:类型转换
指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。
static关键字
public class Application {
private static String name;//静态属性
private int age;//非静态属性
public static void test1(){
System.out.println("静态方法");
//test02()静态方法不可以调用非静态方法
}
public void test02(){
System.out.println("非静态方法");
test1();//非静态方法可以调用静态方法
}
public static void main(String[] args) {
Application.test1();//静态方法建议用类直接调用
System.out.println(Application.name);//通过类来直接调用静态属性
Application application=new Application();
System.out.println(application.age);
application.test02();
}
总结:静态属性和静态方法可以直接类来直接调用,而非静态方法和属性只能通过类的实例化的对象来调用。
非静态方法可以调用静态方法,静态方法不可以调用非静态方法。因为static是与类相关的 而类比对象先出现,所以不能调用还没出现的东西。
匿名代码块,静态代码块,构造方法的执行顺序
public class Application {
{//匿名代码块可以赋初始值
System.out.println("匿名代码块");
}
static {
System.out.println("静态代码块");
}
public Application(){
System.out.println("构造方法");
}
public static void main(String[] args) {
Application application=new Application();
/*执行结果:
静态代码块 只会执行一次 还是因为它和类一起产生的
匿名代码块
构造方法*/
System.out.println("---------------------------");
Application application1 = new Application();
/*执行结果:
---------------------------
匿名代码块
构造方法 */
}
}
//静态导入包
import static java.lang.Math.random;
抽象类
//abstract 抽象类 它是单继承的 但是接口可以实现多继承
public abstract class Action {
//抽象方法 只有方法名 没有方法体
public abstract void something();
}
//继承抽象类 就必须重写抽象类里面的所有抽象方法,除非本身也是抽象类
public class A extends Action {
@Override
public void something() {
}
}
注意点
- 不能new这个抽象类,只能靠子类去实现它
- 抽象类中可以写普通方法
- 抽象类方法必须在抽象类中
接口
//interface 定义接口的关键字
public interface UserServer {
//接口中所有的方法都是抽象的 public abstract
void add(String name);
void delete(String name );
void update(String name);
void query(String name);
}
public interface TimeServers {
void time();
}
//类可以实现接口,implements 接口
//实现了接口中的类,就必须重写接口中的方法
//通过接口就能实现多继承
public class UserServerImpl implements UserServer,TimeServers {
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void time() {
}
}
接口:
构造方法:没有构造方法
成员变量:只能是常量。默认修饰符:public static final
成员方法:jdk1.7只能是抽象的。默认修饰符:public abstract (推荐:默认修饰符请自己永远手动给出)
jdk1.8可以写以default和static开头的具体方法