多态
static关键字的使用
1.修饰成员属性
1.静态属性、类属性
2.可以直接使用类名调用
3.该类的所有成员都共用这个属性
4.在内存中只有一个拷贝,能在类外改变其值
5.只能
示例1:
创建StaticDemo类
public class StaticDemo {
public static String[] array;
public static String staticAttr;
public String attr;
public static void method() {
System.out.println("静态方法");
}
}
创建Demo1类演示static功能
StaticDemo.staticAttr = "hello";
System.out.println(StaticDemo.staticAttr);
StaticDemo staticDemo1 = new StaticDemo();
staticDemo1.attr = "hi1";
staticDemo1.staticAttr = "hello1";
System.out.println(staticDemo1.attr);
System.out.println(staticDemo1.staticAttr);
StaticDemo staticDemo2 = new StaticDemo();
staticDemo2.attr = "hi2";
System.out.println(staticDemo2.attr);
System.out.println(staticDemo2.staticAttr);
StaticDemo.method();
staticDemo1.method();
2.修饰成员方法
1.静态方法、类方法
2.可以直接使用类名调用
3.该类的所有成员公用这个属性
示例2:
创建MathUtil类
public class MathUtil {
public static final double PI = 3.1415;
public static final double E = 2.7182;
public static int plus(int a, int b) {
return a + b;
}
}
创建Main类演示static功能
// 使用数学工具类
System.out.println(MathUtil.PI);
System.out.println(MathUtil.plus(11, 12));
3.修饰代码块
1.静态代码块
2.普通代码块每次创建对象时执行
3.静态代码块只会在类被加载到jvm(第一次使用这个类)中时执行一次。
示例3:
在StaticDemo中添加代码块
public class StaticDemo {
public static String[] array;
{
System.out.println("普通代码块执行");
}
static {
System.out.println("静态代码块执行");
}
static {
array = new String[] {"hello", "hi", "ok"};
}
public static String staticAttr;
public String attr;
public static void method() {
System.out.println("静态方法");
}
}
调用Demo1类演示static功能
代码同上
final关键字的使用
1.修饰成员变量:
常量,初始化之后不可修改值
引用数据类型, 用final修饰不能改变地址
2.修饰成员方法:
该方法无法被重写
3.修饰类:
该类无法被继承
Object
1.属于java.lang包
2.所有的类,如果没有显式声明继承关系,则默认继承Object类
3.Object类中实用的方法:
toString():
1.当我们实用syso打印一个对象时,默认调用它的toString()方法。
2.Object中的实现:类的全限定名+@+对象hash码的16进制形式
3.一般情况都会重写,用于展示对象的所有属性。
Demo02 demo1 = new Demo02();
Demo02 demo2 = new Demo02();
System.out.println(demo1); // org.jgs2007.demo.Demo02@15db9742
System.out.println(demo2); // org.jgs2007.demo.Demo02@6d06d69c
equals():
1.比较引用数据类型的值相等
2.Object中的实现:使用的时==,比较地址相等
System.out.println(student1 == student2); // false 地址不相同,不是同一个对象
System.out.println(student1.equals(student2)); // true
hashCode():
1.获取十进制的hash码
2.每个对象的唯一编码
int hashCode = demo2.hashCode();
String hexString = Integer.toHexString(hashCode);
System.out.println(hexString);
getClass():
1.获取对象所属类的Class对象
2.Class对象用来描述一个类的特征
Class class1 = demo1.getClass();
String name = class1.getName();
System.out.println(name); // org.jgs2007.demo.Demo02 类的全限定名
//简写
System.out.println(demo2.getClass().getName()); // 获取一个对象所属的类
hashCode和equals的关系
1.hashCode不相同,equals一定false
2.hashCode相同,equals不一定true
3.equals为true,hashCode一定相同
4.jvm判断两个对象是否值相等时,先判断hashCode是否相等,如果相等再执行equals,如果不相等,直接判为不相等。
System.out.println(student1 == student2); // false 地址不相同,不是同一个对象
System.out.println(student1.equals(student2)); // true
System.out.println(student1.hashCode());
多态
示例准备
创建一个person类作为父类,以及parent类,teacher类
人类
package org.jgs2007.demo;
/**
* 人类
* @author junki
* @date 2020年7月1日
*/
public class Person {
private String name;
private int age;
private char sex;
public Person() {
super();
}
public Person(String name, int age, char sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
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 char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + sex;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex != other.sex)
return false;
return true;
}
public void eat() {
System.out.println("吃东西");
}
}
教师类
package org.jgs2007.demo;
/**
* 教师类
* @author junki
* @date 2020年7月1日
*/
public class Teacher extends Person {
private int teacherId;
public Teacher() {
super();
}
public Teacher(String name, int age, char sex, int teacherId) {
super(name, age, sex);
this.teacherId = teacherId;
}
public int getTeacherId() {
return teacherId;
}
public void setTeacherId(int teacherId) {
this.teacherId = teacherId;
}
@Override
public String toString() {
return "Teacher [teacherId=" + teacherId + ", name()=" + getName() + ", age=" + getAge() + ", sex="
+ getSex() + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + teacherId;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
Teacher other = (Teacher) obj;
if (teacherId != other.teacherId)
return false;
return true;
}
public void teach() {
System.out.println("老师上课");
}
public void eat() {
System.out.println("上课,废寝忘食");
}
}
家长类
package org.jgs2007.demo;
/**
* 家长类
* @author junki
* @date 2020年7月1日
*/
public class Parent extends Person {
private String mobile;
public Parent() {
super();
}
public Parent(String name, int age, char sex, String mobile) {
super(name, age, sex);
this.mobile = mobile;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((mobile == null) ? 0 : mobile.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
Parent other = (Parent) obj;
if (mobile == null) {
if (other.mobile != null)
return false;
} else if (!mobile.equals(other.mobile))
return false;
return true;
}
public void eat() {
System.out.println("等孩子放学,一起吃饭");
}
}
前提
1.有继承关系
2.向上转型
1.父类引用指向子类对象
2.调用的仍然是重写之后的方法
3.子类中的特有方法无法调用
Person person1 = new Teacher("张三", 18, '男', 12345);
System.out.println(person1); // 使用的仍然时子类的toString方法
//person1.teach();
person1.eat();
Teacher teacher1 = (Teacher) person1;
teacher1.teach();
3.向下转型
只能向下转型为对象的真实类型
public class Animail {
private String name="Animail";
public void eat(){
System.out.println(name+" eate");
}
}
class Human extends Animail{
private String name="Human";
public void eat(){
System.out.println(name+" eate");
}
}
class Main {
public static void main(String[] args) {
Animail a1=new Human();//向上转型
Animail a2=new Animail();
Human b1=(Human)a1;// 向下转型,编译和运行皆不会出错
// Human c=(Human)a2;//不安全的向下转型,编译无错但会运行会出错
}
}
实现多态
1.创建一个方法,方法的参数是父类型
2.调用方法时,传递子类对象
3.传递的对象不同,执行的方法也不同,体现了多态
// 测试多态
Teacher t = new Teacher();
Parent p = new Parent();
test(t);
test(p);
}
// 测试多态
public static void test(Person person) {
person.eat();
}