Java基础之面向对象(三)多态性

一、Object类

Object类是所有Java类的根基类(“祖先类”)

如果在类的声明中未使用extends关键字指明基类,则默认基类为Object类

public class Person{
}

等价于:

public class extends Object{
}

1、toString()方法

(1)Object类中定义有public String toString()方法,其返回值是String类型,描述当前对象的有关信息。

如果直接打印某对象的引用,则默认会调用这个对象的toString()方法,默认打印的内容中包含这个引用所指向的内存地址。

(2)可以根据需要在用户自定义类中重写toString()方法。

2、equals()方法

(1)Object类中定义有public boolean equals(Object obj)方法,提供定义对象是否“相等”的逻辑。

(2)Object的equals方法定义为:x.equals(y),当x和y指向同一个地址时返回true,否则返回false。

(3)String类中已经重写了equals(Object obj)方法,重写后的方法比较的是两个字符串的“内容”是否一样(注意:==比较对象的引用)。

(4)可以根据需要在用户自定义类型中重写equals方法。

package object;

public class Student {
	private String name;
	private int age;
	private double score;

	public Student() {

	}

	public Student(String name, int age, double score) {
		super();
		this.name = name;
		this.age = age;
		this.score = score;
	}

	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 double getScore() {
		return score;
	}

	public void setScore(double score) {
		this.score = score;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
	}

}
package object;

public class ToStringDemo {
	public static void main(String[] args) {
		Student stu = new Student("小明",17,78);
		System.out.println(stu);
	}
}

运行结果:

Student [name=小明, age=17, score=78.0]

package object;

public class EqualsDemo {
	public static void main(String[] args) {
		Student stu1 = new Student("李明",18,88.5);
		Student stu2 = new Student("李明",18,88.5);
		System.out.println("stu1和stu2相等吗?" + stu1.equals(stu2));
	}
}

运行结果:

stu1和stu2相等吗?false


二、多态性

封装是为了保护属性的一种操作,继承是为了扩展类的功能

是由封装性和继承性引出的面向对象程序设计语言的另一种特征


多态的体现

1、从方法的角度来看:

方法的重载与重写

(1)重载(overloading):根据传入的参数不同,完成功能也不同

(2)重写(override):子类根据需求重写父类中的方法。

2、从对象的角度来看:

对象的多态性主要分为两种:

(1)向上转型:子类对象->父类对象(程序会自动完成)

格式:

       父类对象=子类实例

       向上转型后,因为操作的是父类对象,所以无法找到在子类中定义的新方法;但如果子类重写了父类的某个方法,则调用的是重写后的方法。

(2)向下转型:父类对象->子类对象(必须明确的指明要转型的子类类型)

格式:

      子类对象 = (子类)父类实例

      注意:向下转型前先要向上转型

实例1:向上转型

package duotai.upper;

public class Person {
	private String name;
	private int age;

	public Person() {

	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public void say() {
		System.out.println("我是父类方法say(),姓名:"+this.name+",年龄:"+this.age);
	}
	
	public void learn() {
		System.out.println("我是父类的learn()方法,人学习...");
	}
	
	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;
	}

}
package duotai.upper;

public class Student extends Person{
	private double score;

	public Student() {

	}

	public Student(String name,int age,double score) {
		super(name,age);
		this.score = score;
	}

	@Override
	public void learn() {
		System.out.println("学生学习...");
	}
	
	public double getScore() {
		return score;
	}

	public void setScore(double score) {
		this.score = score;
	}

}
package duotai.upper;

public class TestUpper {
	public static void main(String[] args) {
		Student stu = new Student("小明",17,83.5);
		Person per = stu;//向上转型
		per.say();
		per.learn();
	}
}

运行结果:

我是父类方法say(),姓名:小明,年龄:17
学生学习...

实例2:向下转型

package duotai.down;

public class Person {
	private String name;
	private int age;

	public Person() {

	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public void say() {
		System.out.println("我是父类方法say(),姓名:"+this.name+",年龄:"+this.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;
	}

}
package duotai.down;

public class Student extends Person{
	private double score;

	public Student() {

	}

	public Student(String name,int age,double score) {
		super(name,age);
		this.score = score;
	}
	public void learn() {
		System.out.println("学生学习...");
	}
	
	public double getScore() {
		return score;
	}

	public void setScore(double score) {
		this.score = score;
	}

}
package duotai.down;

public class TestDown {
	public static void main(String[] args) {
		Person per = new Student("小明",22,89.5);//向上转型
		Student stu = (Student)per;//向下转型
		stu.learn();
		stu.say();
	}
}

运行结果:

学生学习...
我是父类方法say(),姓名:小明,年龄:22


instanceof关键字

1、在Java中可以使用instanceof关键字判断一个对象是否属于一个类的实例

1、格式:

        对象 instanceof 类 -> 返回boolean类型

实例:

package instanceofdemo;

public class Person {
	private String name;
	private int age;

	public Person() {

	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public void say() {
		System.out.println("我是父类方法say(),姓名:"+this.name+",年龄:"+this.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;
	}

}
package instanceofdemo;

public class Student extends Person{
	private double score;

	public Student() {

	}

	public Student(String name,int age,double score) {
		super(name,age);
		this.score = score;
	}
	public void learn() {
		System.out.println("学生学习...");
	}
	
	public double getScore() {
		return score;
	}

	public void setScore(double score) {
		this.score = score;
	}

}
package instanceofdemo;

public class Farmer extends Person{
	public Farmer() {
		
	}
	
	public Farmer (String name,int age) {
		super(name, age);
	}
	
	public void plant() {
		System.out.println("农民种地...");
	}
}
package instanceofdemo;

public class InstanceofDemo {
	public static void main(String[] args) {
		Student stu = new Student();
		Farmer f = new Farmer();
		method(null);
		method(stu);
		method(f);
		System.out.println("*******************");
		Person p = new Student();
		System.out.println(p instanceof Person);//判断是否是Person类型
		System.out.println(p instanceof Student);//判断是否是Student类型的对象转换过来的
	}
	
	public static void method(Person per) {
		if(per == null) {
			System.out.println("不能直接传递null");
			return;
		}
		if(per instanceof Student) {
			Student stu = (Student)per;
			stu.learn();
		}
		if(per instanceof Farmer) {
			Farmer f = (Farmer)per;
			f.plant();
		}
	}
}

运行结果:

不能直接传递null
学生学习...
农民种地...
*******************
true
true


final关键字

1、在Java中声明类、属性和方法时,可以使用关键字final来修饰。

2、注意:

(1)final修饰变量(成员变量或局部变量),则成为常量,只能复制一次

        final  类型  variableName;

       修饰成员变量时,定义时同时给出初始值,而修饰局部变量时不做要求。

(2)final修饰方法,则该方法不能被子类重写

final  返回值类型  methodName(paramList){

       ...

}

(3)final修饰类,则类不能被继承

final  class finalClassName(

      ...

}


三、抽象类与接口

1、用abstract修饰的类即为抽象类

abstract class 抽象类名{

}

2、抽象类不能被实例化,必须被继承,抽象方法必须被重写,生成它的子类;

3、由abstract修饰的方法就是抽象方法,抽象方法没有方法体;

4、抽象类不一定要包含抽象方法,若类中包含了抽象方法,则该类必须被定义为抽象类;

5、如果一个子类没有实现抽象父类中所有的抽象方法,则子类也称为一个抽象类;

6、构造方法、静态方法、私有方法、final方法不能被声明为抽象的方法。


实例:

package abstractdemo;

public abstract class Animal {
	private String name;
	private String food;
	
	public Animal() {
		
	}

	public Animal(String name, String food) {
		this.name = name;
		this.food = food;
	}
	
	//抽象方法只声明,不实现
	public abstract void eat();
}
package abstractdemo;

public class Cat extends Animal {

	private String fur;

	public Cat() {

	}

	public Cat(String name, String food, String fur) {
		super(name, food);
		this.fur = fur;
	}

	@Override
	public void eat() {
		System.out.println("小猫吃鱼...");
	}

	public String getFur() {
		return fur;
	}

	public void setFur(String fur) {
		this.fur = fur;
	}

}
package abstractdemo;

public class Dog extends Animal {
	private String color;

	public Dog() {

	}

	public Dog(String name, String food, String color) {
		super(name, food);
		this.color = color;
	}

	@Override
	public void eat() {
		System.out.println("小狗啃骨头...");
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

}
package abstractdemo;

//如果子类也是一个抽象类,则可以不用重写父类的抽象方法
public abstract class Tiger extends Animal {
	public abstract void run();
}
package abstractdemo;

public class TestAnimal {
	public static void main(String[] args) {
		Animal animal1 = new Cat();//由猫对象向上转型
		Animal animal2 = new Dog();//由狗对象向上转型
		animal1.eat();
		animal2.eat();
	}
}

运行结果:

小猫吃鱼...
小狗啃骨头...


接口

1、接口(interface)是抽象方法和常量值的定义的集合;

2、接口是一种“标准”、“契约”;

3、从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。


接口的声明语法

1、包括接口声明和接口体

2、完整的接口声明:

[public]  interface  接口名称[extends listOfSuperInterface] { ... }

3、接口体包括常量定义和方法定义

(1)常量定义:type Name = value;    该常量被实现该接口的多个类共享;具有public、final、static的属性

(2)方法体定义:具有public和abstract属性


接口的实现类

1、与抽象类一样,接口要使用也必须通过子类,子类通过implements关键字实现接口;

2、一个类可以实现多个接口,在implements子句中用逗号隔开;

3、非抽象子类必须实现接口中定义的所有方法;

4、实现格式:

     class  子类  implements  接口A,接口B,...{}


接口的使用规则

1、接口中所有的方法都是public abstract;

2、在接口中声明方法时,不能使用static、final、synchronized、private、protected等修饰符;

3、一个接口可以继承自另一个接口;

4、Java中不允许类的多继承,但允许接口的多继承;

5、接口中可以有数据成员,这些成员默认都是public static final。


接口的用途

用处

1、通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系;

2、通过接口指明多个类需要实现的方法;

3、通过接口了解对象的交互界面,而无需了解对象所对应的类。


实例:

package interfacedemo;

/**
 * 飞翔接口
 */
public interface Fly {
	public static final int SPEED = 200;
	public abstract void fly();
}
package interfacedemo;

/**
 * 散步接口
 */
public interface Walk {
	public void walk();
}
package interfacedemo;

public class Bird implements Fly,Walk {

	@Override
	public void fly() {
		System.out.println("小鸟飞翔...");
	}

	@Override
	public void walk() {
		System.out.println("小鸟散步...");
	}

}
package interfacedemo;

public class Kite implements Fly {

	@Override
	public void fly() {
		System.out.println("风筝飞翔...");
	}

}
package interfacedemo;

public class Test {
	public static void main(String[] args) {
		Fly f1 = new Kite();
		f1.fly();
		Fly f2 = new Bird();
		f2.fly();
		Walk w = new Bird();
		w.walk();
	}
}

运行结果:

风筝飞翔...
小鸟飞翔...
小鸟散步...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值