1.多态
上篇文章我们给大家介绍了Java中三大特性中的继承,本文给大家介绍另一个特性——多态。首先给大家介绍的就是多态的概念。
1.1多态的概述
- 什么是多态:
同一个对象,在不同时刻表现出来的不同形态
- 多态的前提:
- 要有继承或实现关系
- 要有方法的重写
- 要有父类引用指向子类对象
1.2多态中的成员访问特点
- 成员访问特点
- 成员变量:
编译看父类,运行看父类
- 成员方法:
编译看父类,运行看子类
为了让大家更好地理解该知识点,我们简单的给大家举一个案例,具体如下:
- 动物类
public class Animal {
public int age = 40;
public void eat() {
System.out.println("动物吃东西");
}
}
- 猫类
public class Cat extends Animal {
public int age = 20;
public int weight = 10;
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉迷藏");
}
}
- 测试类
public class AnimalDemo {
public static void main(String[] args) {
//有父类引用指向子类对象
Animal a = new Cat();
System.out.println(a.age);
// System.out.println(a.weight);
a.eat();
// a.playGame();
}
}
该案例执行的结果如下:
1.3多态的优点和缺点
- 优点
提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
- 缺点
不能使用子类的特有成员
1.4多态中的转型
- 向上转型
父类引用指向子类对象就是向上转型
- 向下转型
格式:子类型 对象名 = (子类型)父类引用;
为了让大家更好的理解这个知识点,我们稍微改一下上述的代码;
- 动物类
public class Animal {
public void eat() {
System.out.println("动物吃东西");
}
}
- 猫类
public class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉迷藏");
}
}
- 测试类
public class AnimalDemo {
public static void main(String[] args) {
//多态
//向上转型
Animal a = new Cat();
a.eat();
// a.playGame();
//向下转型
Cat c = (Cat)a;
c.eat();
c.playGame();
}
}
以上的案例实现的代码执行结果具体如下:
1.5多态的案例
- 案例需求
请采用多态的思想实现猫和狗的案例,并在测试类中进行测试
- 代码实现
- 动物类
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
System.out.println("动物吃东西");
}
}
- 猫类
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
public void eat() {
System.out.println("猫吃鱼");
}
}
- 狗类
public class Dog extends Animal {
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
public void eat() {
System.out.println("狗吃骨头");
}
}
- 测试类
public class AnimalDemo {
public static void main(String[] args) {
//创建猫类对象进行测试
Animal a = new Cat();
a.setName("加菲");
a.setAge(5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
a = new Cat("加菲", 5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
}
}
以上案例代码的实现思路如下:
2.抽象类
2.1抽象类的概述
当我们在做子类共性功能抽取时,有些方法在父类中并没有具体的体现,这个时候就需要抽象类了! 在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类!
2.2抽象类的特点
- 抽象类和抽象方法必须使用
abstract
关键字修饰
//抽象类的定义
public abstract class 类名 {}
//抽象方法的定义
public abstract void eat();
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类不能实例化
抽象类如何实例化呢?参照多态的方式,通过子类对象实例化,这叫抽象类多态
- 抽象类的子类
要么重写抽象类中的所有抽象方法 要么是抽象类
2.3抽象类的成员特点
- 成员的特点
- 成员变量
- 既可以是变量
- 也可以是常量
- 构造方法
- 空参构造
- 有参构造
- 成员方法
- 抽象方法
- 普通方法
接下来我们还是对以上的案例稍作改动来说明该特点;具体代码如下:
- 动物类
public abstract class Animal {
private int age = 20;
private final String city = "北京";
public Animal() {}
public Animal(int age) {
this.age = age;
}
public void show() {
age = 40;
System.out.println(age);
// city = "上海";
System.out.println(city);
}
public abstract void eat();
}
- 猫类
public class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
}
- 测试类
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
a.eat();
a.show();
}
}
以上案例代码的实现思路如下:
2.4抽象类的案例
- 案例需求
请采用抽象类的思想实现猫和狗的案例,并在测试类中进行测试
- 具体用代码实现如下:
- 动物类
public abstract class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public abstract void eat();
}
- 猫类
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
public void eat() {
System.out.println("猫吃鱼");
}
}
- 狗类
public class Dog extends Animal {
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
public void eat() {
System.out.println("狗吃骨头");
}
}
- 测试类
public class AnimalDemo {
public static void main(String[] args) {
//创建对象,按照多态的方式
Animal a = new Cat();
a.setName("加菲");
a.setAge(5);
System.out.println(a.getName()+","+a.getAge());
a.eat();
System.out.println("--------");
a = new Cat("加菲",5);
System.out.println(a.getName()+","+a.getAge());
a.eat();
}
}
具体执行的结果如下:
3.修饰符
3.1 package
- 1、包的概念
- 包就是文件夹,用来管理类文件的
- 2、包的定义格式
-
package 包名; (多级包用.分开)
- 例如:
package com.heima.demo;
- 3、带包编译&带包运行
- 带包编译:
javac –d . 类名.java
- 例如:
javac -d . com.heima.demo.HelloWorld.java
- 带包运行:
java 包名+类名
- 例如:
java com.heima.demo.HelloWorld
3.2 import
- 导包的意义
使用不同包下的类时,使用的时候要写类的全路径,写起来太麻烦了
为了简化带包的操作,Java就提供了导包的功能
- 导包的格式
格式:import 包名;
范例:import java.util.Scanner;
- 示例代码(没有使用导包,创建的Scanner对象)
package com.heima;
public class Demo {
public static void main(String[] args) {
// 1. 没有导包,创建Scnaner对象
java.util.Scanner sc = new java.util.Scanner(System.in);
}
}
- 示例代码(使用导包后,创建的Scanner对象)
package com.heima;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
// 1. 没有导包,创建Scnaner对象
Scanner sc = new Scanner(System.in);
}
}
3.3 权限修饰符
3.4 final
- fianl关键字的作用
- final代表最终的意思,可以修饰成员方法,成员变量,类
- final修饰类、方法、变量的效果
- fianl修饰类:该类不能被继承(不能有子类,但是可以有父类)
- final修饰方法:该方法不能被重写
- final修饰变量:表明该变量是一个常量,不能再次赋值
3.5 final修饰局部变量
- fianl修饰基本数据类型变量
- final 修饰指的是基本类型的数据值不能发生改变
- final修饰引用数据类型变量
- final 修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的
为了方便大家理解相应的知识点,我们给出一个简单的案例:
public static void main(String[] args){
final Student s = new Student(23);
s = new Student(24); // 错误
s.setAge(24); // 正确
}
3.6 static
- static的概念
- static关键字是静态的意思,可以修饰【成员方法】,【成员变量】
- static修饰的特点
- 被类的所有对象共享,这也是我们判断是否使用静态关键字的条件
- 可以通过类名调用当然,也可以通过对象名调用【推荐使用类名调用】
为了方便大家的理解该知识点,我们给出一个简单的案例,具体实现如下:
class Student {
public String name; //姓名
public int age; //年龄
public static String university; //学校 共享数据!所以设计为静态!
public void show() {
System.out.println(name + "," + age + "," + university);
}
}
public class StaticDemo {
public static void main(String[] args) {
// 为对象的共享数据赋值
Student.university = "51CTO博客";
Student s1 = new Student();
s1.name = "一计之长";
s1.age = 30;
s1.show();
Student s2 = new Student();
s2.name = "风清扬";
s2.age = 33;
s2.show();
}
}
该案例具体执行的结果如下:
3.7 static访问特点
- static的访问特点
- 非静态的成员方法
- 能访问静态的成员变量
- 能访问非静态的成员变量
- 能访问静态的成员方法
- 能访问非静态的成员方法
- 静态的成员方法
- 能访问静态的成员变量
- 能访问静态的成员方法
- 总结成一句话就是:
- 静态成员方法只能访问静态成员
总结
本文给大家介绍了Java中的三大特性之一——多态,主要介绍了多态的概念、成员访问特点、优点以及缺点;另外还介绍了抽象类以及Java中的修饰符。并且最后就是通过一些案例说明该知识点是如何使用的,帮助大家更好的理解。