在Java中,多态是指不同类的对象在调用同一个方法时所呈现出的多种不同行为。在一个类中定义的属性和方法被其他类继承或重写之后,当把子类对象直接赋值给父类引用变量时,相同引用类型的变量调用同一个方法所呈现在的多种不同形态。通过多态,消除类之间的耦合关系,大大提高程序的可扩展性和可维护性。多态性是由类的继承,方法重写以及父类引用指向子类对象体现的。程序只有在运行时程序才知道具体代表的是哪个子类对象,这就体现了多态性。
package com.wang.demo6;
//父类
public class Person {
public void run() {
System.out.println("run");
}
}
===================================
package com.wang.demo6;
//子类
public class Student extends Person {
@Override
public void run() {
System.out.println("son");
}
public void eat() {
System.out.println("eat");
}
}
===================================
package com.wang.demo6;
//测试类
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();
//对象能执行那些方法,主要看对象左边的类型
s2.run();//子类重写了父类的方法,执行子类重写后的方法
s1.run();
}
}
多态的注意事项:
多态指的是方法的多态,属性没有多态
存在继承关系,即有父子关系
子类继承父类的方法需要重写
父类引用指向子类对象
在Java中,提供了一个关键字instanceof , 它可以判断一个对象是否为某个类(或接口)的实例或者子类实例,就是判断是否存在父子关系。
使用 instanceof 关键字的格式:
对象(或者对象引用变量) instanceof 类(或接口)
package com.wang.demo7;
//主程序
public class Application {
public static void main(String[] args) {
//利用 instanceof 关键字判断是否存在父子关系
//System.out.println(X instanceof Y);
/*
* Object > String
* Object > Person > Teacher
* Object > Person > Student
* */
Object object = new Student();
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 = 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); //编译报错
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); //编译报错
}
}
在多态中,将子类对象当作父类类型使用的情况,在Java中叫做向上转型,这种方式不需要任何显式声明,但需要注意的是,此时不能够通过父类变量去调用子类特有的方法。
package com.wang.demo1;
public class Application {
public static void main(String[] args) {
//类型之间的转化: 父 子
//高 低
Person person = new Student();
//将 person 对象转换为 Student类型,就可以使用 Student 类型的方法
((Student)person).go();
//强制转换,高类型 强制转换为 低类型
/*
Student person1 = (Student) person;
person1.go();
*/
}
}
强制转换需要注意的:
1.把子类转换为父类,向上转型;
2.把父类转换为子类,向下转型,需要强制转型;
3.方便方法的调用,减少重复的代码
在定义一个类时,只是在描述某类事物的特征和行为,并没有产生具体的数据。只有通过 new 关键字创建该类的实例对象后,系统才会为每个对象分配内存空间,存储各自的数据。有时候,开发人员会希望某些特定的数据在内存中只有一份,而且能被一个类的所有实例对象共享。
使用 static 关键字来修饰的成员变量,称为静态变量,它可以被所有实例所共享。或者说,加上 static 的属性是类属性,静态属性。
静态变量的使用格式:
1.类名.变量名(推荐)
2.对象实例名.变量名
注意: static 关键字只能用于修饰成员变量,不能用于修饰局部变量,否则编译会报错
package com.wang.staticdemo1;
public class Student {
static String name;
}
============================
package com.wang.staticdemo1;
public class Application {
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student();
Student.name = "小明"; //类名.变量名
System.out.println("我是" + student1.name);
System.out.println("我是" + student2.name);
}
}
之前,要是想使用类中的成员方法,就需要先将这个类实例化,有时候希望在不创建对象的情况下就可以调用某个方法,这需要在类中定义的方法前加上 static 关键字即可。
静态方法访问的格式:
1.类名.方法名(推荐)
2.实例对象名.方法名
注意:静态方法只能调用 静态方法
非静态方法可以调用 静态方法 和 非静态方法
package com.wang.staticdemo2;
public class Person {
//定义静态方法
public static void say() {
System.out.println("Hello");
}
}
==================================
package com.wang.staticdemo2;
public class Application {
public static void main(String[] args) {
//使用 类名.方法名 的方式调用
Person.say(); //Hello
//实例化对象
Person person = new Person();
//使用 实例对象名.方法名 的方式调用
person.say(); //Hello
}
}
使用一对大括号包围起来的若干代码被称为一个代码块,用 static 关键字修饰的代码块称为静态代码块。当类被加载时,静态代码块会执行,由于类只加载一次,所以静态代码块也只执行一次,在程序中,通常会使用静态代码块来对类的成员变量进行初始化。
静态代码块格式:
static {
...
}
package com.wang.staticdemo3;
public class Person {
//第二个执行
{
System.out.println("匿名代码块");
}
//第一个执行,而且只执行一次
static {
System.out.println("静态代码块");
}
//第三个执行
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
System.out.println("===================");
Person person2 = new Person();
}
}
package com.wang.demo2;
//静态导入包
import static java.lang.Math.random;
public class Test {
public static void main(String[] args) {
/*
* 随机数,java.lang.Math包下的一个 random()方法
* System.out.println(Math.random());
*/
//有一种方法,不用使用 Math.random() ,
//也可以使用 random()方法
System.out.println(random());
}
}