父类-Creator
//生物类
public class Creator {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Creator() {
super();
System.out.println("Creator构造方法执行了");
}
}
Creator的子类-Animal
//动物类
public class Animal extends Creator {
private String name;//名字
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Animal() {
super();
System.out.println("Animal类构造方法执行了");
}
}
Animal的子类-Dog
//狗类
public class Dog extends Animal{
private String hostName;//主人的名字
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
public Dog() {
super();
System.out.println("dog类的无参构造方法执行了");
}
}
测试类TestDog
public class TestDog {
public static void main(String[] args) {
Dog d=new Dog();
d.setAge(12);
d.setName("旺财");
d.setHostName("刘长安");
System.out.println("age:"+d.getAge()+",name:"+d.getName()
+",hostName:"+d.getHostName());
}
}
/*
1.什么是多态性?
(1)同一个动作与不同的对象产生不同的行为
(2)多态指的是一个对象的多种形态
2.多态的体现方式
(1)使用继承,不同的子类重写父类方法后,体现出的形式不一样
(2)接口的实现
3.形成多态的必要条件
(1)继承:存在子类和父类的关系(子类的形态和父类的形态)
(2)接口的实现:定义了一个实现对应的接口
(3)重写:子类重写了父类的方法(调用重写前后的方法)
(4)重载:调用相同的方法名,实现的功能是不一样的 (相同的方法名,操作不同)
(5)子类对象的多态性(重点):父类的引用指向子类的实例
4.程序分为两种状态,一个编译状态,一个是运行状态
* 对于多态来说,编译时看左边,你这个对象是定义的是什么类型就是什么类型,将pet对象看做是Pet类型
* 运行时,看右边,真正执行的对象,也就是子类对象(Dog),执行的也是子类重写后的方法。
*
* 5.上转型和下转型
* (1)上转型:将子类对象交给父类引用,可以自动转换
* (2)下转型:把父类转成子类 强制类型转换
*
* 6.对象的多态性
* (1).父类的引用指向子类的实例
* (2).在编译期间调用的父类的方法,真正执行的时候,执行的是子类的方法
* (3).编译看左边,运行看右边
*/
Pet(宠物类)---Dog和Penguin的父类
//宠物类
public class Pet {
private String name;//昵称
protected int health=100;//健康值
protected int love=0;//亲密的
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public Pet(String name, int health) {
super();
this.name = name;
this.health = health;
}
public Pet(String name) {
super();
this.name = name;
}
public Pet() {
super();
}
//吃食
public void eat(){
System.out.println("宠物吃食");
}
//打印宠物信息
public void info(){
System.out.println("名字叫:"+this.name+",我的健康值是:"+this.health+",我和主人的亲密度:"+this.love);
}
}
Dog类,狗类
//狗类
public class Dog extends Pet {
private String starin;//品种
public String getStarin() {
return starin;
}
public void setStarin(String starin) {
this.starin = starin;
}
public Dog() {
super();
}
public Dog(String name, String starin) {
super(name);
this.starin = starin;
}
//重写吃饭的方法
public void eat(){
super.health=super.health+3;//吃饱以后健康值加3
System.out.println("狗狗吃饱了,健康值加3");
}
//重写输出的方法
public void info(){
super.info();//调用父类未重写前的方法
System.out.println("我的品种是:"+this.starin);
}
public void sleep(){
System.out.println("狗狗在呼呼大睡");
}
//接飞盘
public void catchingFlyDisc(){
System.out.println("狗狗正在接飞盘:");
super.love=super.love+5;
super.health-=10;
}
}
Penguin类,企鹅类
//企鹅类
public class Penguin extends Pet{
private String sex;//性别
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Penguin() {
super();
}
public Penguin(String name,String sex) {
super(name);
this.sex = sex;
}
//重写吃饭的方法
public void eat(){
super.health=super.health+5;
System.out.println("企鹅吃饱了,健康值加5");
}
//重写输出的方法
public void info(){
super.info();
System.out.println(",我的性别是:"+this.sex);
}
//游泳
public void swimming(){
System.out.println("企鹅正在游泳:");
super.love=super.love+5;
super.health-=10;
}
}
Master,主人
//主人类
public class Master {
private String hostName;//主人姓名
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
//给狗狗喂食
public void feed(Dog dog){
dog.eat();
}
//给企鹅喂食
public void feed(Penguin p){
p.eat();
}
//玩游戏
public void play(Pet pet){
if(pet instanceof Dog){
Dog dog=(Dog)pet;
dog.catchingFlyDisc();
dog.info();
}else if(pet instanceof Penguin){
Penguin p=(Penguin)pet;
p.swimming();
p.info();
}
}
}
instanceof关键字,用来测试当前对象是属于哪一个类。instanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。
运行结果截图
Person类,final关键字的作用
/**
* final关键字:代表最终的意思
* 可以修饰什么?
* 1.修饰类
* 2.修饰方法
* 3.修饰成员变量
* 4.修饰局部变量
*
* 修饰类,这个类有什么特点?
* 这个类不能被继承,他就是一个(太监类),但是可以继承别的类(顶级父类object)
*
* 修饰方法,这个方法有什么特点?
* 代表这个方法是一个最终方法,不能被重写可以被重载
*
* 修改成员变量有什么特点?成员变量的值不可改变
* 1.成员变量不会再有默认值
* 2.如果使用final关键字,必须直接对成员变量进行赋值
*
* 修饰局部变量的特点。局部变量的值不能改变,一般用它修饰一个常量
* 可以先不赋值,但是赋值之后不可更改其值。
*
*/
public class Person {
private String name;
private final String sex="男";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public final void eat(){
System.out.println("吃饭");
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + "]";
}
}
在Person的子类中重写eat()方法会报错,final关键字修饰的方法不能被重写。
TestPerson,final关键字功能的简单测试
public class TestPerson {
public static void main(String[] args) {
Person p=new Person();
p.setName("小明");
System.out.println(p.toString());
final int num=10;
//num=20;会报错
System.out.println(num);
final int A;
A=10;
//A=12;会报错
}
}
SportsMan,static关键字的作用
/**
* static :静态的
* 1.static修饰成员变量(类变量)
* (1).修饰成员变量,这个变量就不属于对象了,而属于类本身,我们就可以通过"类名.属性名"来调用,前提修饰符不能是私有的private。
* (2).只要通过我这个类创建的对象,这些对象都可以共享这个属性
* (3).当其中一个对象对类变量进行更改以后,其他对象的这个类变量也会更改,
* VS实例变量(非static的变量,属于对象本身,各个对象都各自有一套副本,不同对象的属性值互不影响)
* (4).类变量是随着类的加载而加载,类变量的生命周期大于实例变量,这个类结束之后类的生命周期才会结束,实例变量是对象不用之后就会结束。
* (5).类变量放在方法区的静态域里面。
* * 2.static修饰方法(类方法)
* (1).修饰方法,这个方法就属于类本身了,我可以通过"类名.方法名()"进行调用
* (2).随着类而加载
* (3).在静态方法里面只能调用静态变量和静态方法,相反在普通放里面可以调用静态方法和静态变量,因为静态方法或静态变量
* 加载时机早于实例变量和实例方法的加载时机(类加载比对象加载时间要早,而且结束时间类要晚)
* (4).不能使用this和supper关键字(编译阶段,对象没有创建,所以不能用this()指代当前对象和super关键字)
*
* 3.static修饰代码块
* 代码块的作用完成初始化
* (1)非静态代码块:
* 可以给类的属性进行初始化操作,同时还可以调用类的方法(静态的 ,非静态的);
* 里面可以有输出语句
* 每创建完一个对象,非静态代码块就加载一次
*
* (2)静态代码块
* 里面可以有输出语句
* 随着类加载而加载,只会执行一次
* 静态代码的加载时机早于非静态代码块(构造代码块)
* 静态代码块里面只能调用类变量和类方法
* 作用:jdbc 驱动 用户名 密码 数据库的连接地址
*
* 对属性赋值:(1)默认初始化 (2)显示的初始化 (3)通过set方法或者构造方法 (4)代码块
* *
*/
public class SportsMan {
//实例变量
private String name;
private int age;
//类变量
static String nation="中国";
//代码块:初始化
{
name="张三";
age=12;
show();
show1();
nation="1";
System.out.println("非静态的代码块");
}
//前面加一个static就是一个静态代码块
static{
// name="李四";
// show();
show1();
System.out.println("这是一个静态代码块");
}
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 String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
public SportsMan(String name, int age) {
super();
this.name = name;
this.age = age;
}
public SportsMan() {
super();
}
@Override
public String toString() {
return "SportsMan [name=" + name + ", age=" + age + ", nation=" + nation + "]";
}
//普通方法
public void show(){//加载时机晚
// System.out.println(this.age);
// System.out.println(nation);
// show1();
System.out.println("这是一个普通方法");
}
//静态方法
public static void show1(){//加载的时机早
// //this代表当前对象
// System.out.println(nation);
// //show();
System.out.println("这是一个静态方法");
}
}
TestSportsMan,static关键字的功能简单测试
public class TestSportsMan {
public static void main(String[] args) {
SportsMan s1=new SportsMan("老王", 35);
SportsMan s2=new SportsMan("老李", 32);
s1.setNation("中国");
SportsMan.nation="china";
s1.show();
SportsMan.show1();
System.out.println(s1);
System.out.println(s2);
}
}
运行截图
静态代码块只会随类的加载执行一遍,而构造代码块会随对象的创建而执行,有几个对象创建就会执行几遍。
执行的一般顺序:
先执行静态方法块,然后对象创建先跳转构造方法从构造方法里的代码不执行跳到构造方法块,然后在跳回构造方法继续执行。
静态方法块>构造(非静态)代码块>构造方法