面对对象-多态
步骤:
1.要有继承(或实现)关系
2.要有方法重写
3.父类引用指向子类对象
父类:
package demo3.多态;
public class Animal {
public void test(){
}
public void eat(){
System.out.println("动物以食为天...");
}
}
子类:
package demo3.多态;
public class Dog extends Animal{
//Ctrl + O
@Override
public void eat() {
System.out.println("狗吃骨头...");
}
}
测试类:
package demo3.多态;
public class Test {
public static void main(String[] args) {
// 对象可以点出什么, 看的是左边声明的类型
// 父类引用 指向 子类对象
Animal animal = new Dog();
// Animal animal = new Animal();
//运行时绑定:具体执行的方法看右边 new 的是什么类型的对象
animal.eat();
// animal.test();
}
}
父类型变量作为参数时,可以接收任意子类对象
父类:
package demo3.多态2;
public class Animals {
/**
* 1.继承,接口实现
* 2.重写
* 3.父类引用指向子类对象
*/
public void eat(){
System.out.println("Animal 类的eat方法...");
}
}
子类:
package demo3.多态2;
import demo3.多态.Animal;
public class Dogs extends Animal {
//Ctrl + O
@Override
public void eat() {
System.out.println("狗吃骨头...");
}
public void watch() {
System.out.println("我还要看家...");
}
}
package demo3.多态2;
import demo3.多态.Animal;
public class Cats extends Animal {
@Override
public void eat() {
System.out.println("猫正在高兴吃着猫粮...");
}
}
package demo3.多态2;
public class Util {
public void eat(Animals animals){
animals.eat();
}
}
测试类:
package demo3.多态2;
public class Test {
public static void main(String[] args) {
Util util = new Util();
Animals animals = new Animals();
util.eat(animals);//Animal 类的eat方法...
animals = new Cats(); //错误
util.eat(animals);
animals = new Dogs();//错误
util.eat(animals);
}
}
多态关系中成员变量的使用
需求:子父类中定义了同名的成员变量,如何调用
分析:A : 子父中定义同名属性name并分别初始化值:String name;
B : 在测试类中以多态的方式创建对象并打印name的属性值:Animal animal = new Dog();
C : 在测试类中以普通方式创建对象并打印name的属性值:Dog dog = new Dog();
结论:
成员变量不能重写
成员变量的使用,取决于调用该变量的类型,成员变量不能重写
父类:
package demo3.多态3;
public class Parent {
String name = "父类中的name";
public void introductian(){
System.out.println("父类的自我介绍方法...");
}
}
子类:
package demo3.多态3;
public class Child extends Parent{
String name = "子类中的name";
@Override
public void introductian() {
System.out.println("子类中的自我介绍方法...");
}
}
测试类:
package demo3.多态3;
public class Test {
public static void main(String[] args) {
//父类引用 指向 子类对象
Parent parent = new Child();
//通过父类引用 调用 成员变量,取的是父类的变量值
System.out.println(parent.name);//父类中的name
//通过父类引用调用成员方法,具体调用的是什么方法看右边 new 的是什么类型的对象
parent.introductian();//子类中的自我介绍方法...
Child child = new Child();
System.out.println(child.name);//子类中的name
}
}
向上转型(自动类型转换)
//子类型转换成父类型
Animal animal = new Animal();
向下转型(强制类型转换)
//父类型转换成子类型
Dog dog = (Dog)animal;
注意:
只能在继承层次内进行转换,否则可能造成异常(ClassCastExceptio) 将父类对象转换成子类之前,使用 instanceof 进行检查
public static void main(String[] args) {
Parent parent = new Child();
if (parent instanceof Child){
Child child = (Child)parent;
child.study("数学");//我正在学习数学
}else {
System.out.println("parent 对象 不是 Child 类型,不可以进行强制类型转换!!!");
}
测试类2:
Child child = new Child();
boolean b = child instanceof Child;//true
System.out.println("b = " + b);
boolean b1 = child instanceof Parent;//true
System.out.println("b1 = " + b1);
boolean b2 = child instanceof Object;//true
System.out.println("b2 = " + b2);
父类:
package demo3.多态3;
public class Parent {
String name = "父类中的name";
public void introductian(){
System.out.println("父类的自我介绍方法...");
}
}
子类:
package demo3.多态3;
public class Child extends Parent{
String name = "子类中的name";
@Override
public void introductian() {
System.out.println("子类中的自我介绍方法...");
}
public boolean study(String subject){
System.out.println("我正在学习" + subject);
return true;
}
}
测试类:
package demo3.多态3;
public class Test1 {
public static void main(String[] args) {
Parent parent = new Child();
Child child = (Child)parent;
child.study("语文");//我正在学习语文
}
}
final关键字
概念:最终的、最后的
作用:用于修饰类、方法和变量
修饰类:该类不能被继承String,System
修饰方法:该方法不能被重写 不能与abstract共存
修饰变量:最终变量,即常量,只能复制一次
static关键字
作用:
用于修饰类的成员:
成员变量:类变量
成员方法:类方法
调用方式:
类名.变量名
类名.方法名(参数)
static 修饰成员变量
特点:
被本类所有的对象共享
注意:
随意修改静态变量的值是有风险的,为了降低风险,可以同时用final关键字修饰,即公有静态常量(注意命名的变化)。
package demo3.多态;
public class Child extends Parent {
/**
* 名字
*/
static String name = "儿子";
}
package demo3.多态;
public class Text {
public static void main(String[] args) {
System.out.println("name= " + Child.name);//name= 儿子
}
}
静态方法:
静态方法中没有对象this,所以不能访问非静态成员
静态方法的使用场景
只需要访问静态成员 不需要访问对象状态,所需参数都由参数列表显示提供
package demo3.多态;
public class Child extends Parent {
/**
* 名字
*/
static String name = "儿子";
int age;
/**
* static 修饰的成员变量
* 1. 通过类名来调用
* 2. 不可以使用非静态成员(包括非静态成员变量和非静态成员方法),
* 即不可以使用this关键字和 super关键字
*
* @return
*/
public static String introduce(){
test();
return "我是:" + name;
}
public static void test(){
System.out.println(name);
}
}
package demo3.多态;
public class Text {
public static void main(String[] args) {
String introduce = Child.introduce();//儿子
System.out.println("introduce = " + introduce);//introduce = 我是:儿子
Child.introduce();//儿子
}
}
需求:定义静态方法。反转数组中的元素
package demo3.多态3;
public class ReverseDemo {
//定义一个静态方法,反转输出数组的元素,例如{1,2,3,4,5}
//6
//5
//4
//...
//1
public static void reverse(int[] arr){
for(int i = arr.length - 1;i >= 0;i--){
System.out.println(arr[i]);
}
}
}
package demo3.多态3;
public class ReverseDemo_Test {
public static void main(String[] args) {
int[] nums = {1,2,3,4,5,6};
ReverseDemo.reverse(nums);
}
}
接口
概念:
interface 接口名 {}
class 类名 implements 接口名{}
package demo3.接口;
/**
* 类可以实现接口 通过 implements 关键字
* 一个非抽象类实现了一个接口,则该类必须实现接口中所有的抽象方法
*/
//Alt + Enter 显示报错
public class Parent implements MyInterface{
@Override
public void text() {
System.out.println("Parent.text");
}
@Override
public void text2() {
}
@Override
public void text3() {
}
}
/**
* 1.接口中所有的方法默认都是 public abstract
* 2.abstract 修饰的方法为抽象方法。抽象方法不需要有方法体
*
* 3.接口和接口之间是继承关系
* 4.一个接口可以继承多个接口
* 5.接口中成员的成员变量 都是 public static final 的常量
*
* 接口中 使用 default and static 修饰的方法
* default 修饰接口中的方法:
* 1.必须要有方法;
* 2.调用方式:通过实现类的对象调用
*
* static 修饰接口中的方法:
* 1.必须要有方法体;
* 2.调用方式:只可以通过 接口名 来调用;
*/
Interface2:
package demo3.接口;
public interface Interface2 {
void text2();
}
Interface3:
package demo3.接口;
public interface Interface3 {
void text3();
}
MyInterface:
package demo3.接口;
public interface MyInterface extends Interface2,Interface3{
int age = 18;//final
void text();
default void defaultMethod(){
System.out.println("MyInterface.defaultMethod");
}
static void staticMethod(){
System.out.println("MyInterface.staticMethod");
}
}
测试类:
package demo3.接口;
public class Test {
public static void main(String[] args) {
Parent parent = new Parent();
System.out.println("parent.age = " + parent.age);//parent.age = 18
System.out.println(parent.age);//18
System.out.println(MyInterface.age);//18
parent.defaultMethod();//MyInterface.defaultMethod
MyInterface.staticMethod();//MyInterface.staticMethod
}
}
接口成员的特点
public static final 常量名 = 常量值;
public abstract 返回值类型 方法名();
public default 返回值类型 方法名(){}static 返回值类型 方法名() {}
private 返回值类型 方法名(){}