方法覆盖
当父类的方法不能满足子类的需求、子类可以对这个方法进行重写、以覆盖父类中的方法。
方法覆盖要求:
1.子类定义的新方法(覆盖方法)和父类中被覆盖的方法要在返回类型、名称和参数列表上保持一致。
2.可选的@Override备注
注意:类方法(静态方法)是无法覆盖的,但可以隐藏。
package lesson008;
public class HideStaticMethodTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
B b=new B();
b.staticMethod();
}
static class A{
public static void staticMethod(){
System.out.println("class A");
}
}
static class B extends A{
public static void staticMethod(){
System.out.println("class B");
}
}
}
运行结果:
class B
多态
1.对象变量的多态
把子类对象赋值给父类对象时向上转型,可以自动进行
把父类对象复制给子类是向下转型,不能自动进行,需要进行类型强制转换操作。如果父类对象变量引用的对象的实际类型是父类,就不能强制转为子类。转型前,可以用instanceof操作符来判断。返回值为boolean类数值。
转型类名的实例 instanceof 父类或子类名
package lesson008;
public class CastingTest {
static class animal{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public animal(String name){
this.name=name;
}
}
static class Cat extends animal{
private String eyes_color;
public String getEyes_color() {
return eyes_color;
}
public void setEyes_color(String eyes_color) {
this.eyes_color = eyes_color;
}
public Cat(String name,String eyes_color) {
super(name); //显示调用父类构造器给name赋值
this.eyes_color=eyes_color;
}
}
static class Dog extends animal{
private String skin_color;
public String getSkin_color() {
return skin_color;
}
public void setSkin_color(String skin_color) {
this.skin_color = skin_color;
}
Dog(String name,String skin_color){
super(name);
this.skin_color=skin_color;
}
}
/*内部类是动态的,也就是开头以public class开头。而主程序是public static class main。在Java中,
* 类中的静态方法不能直接调用动态方法。只有将某个内部类修饰为静态类,然后才能够在静态类中调用该类的成员变量与成员方法。
所以 解决办法是将public class改为public static class.*/
public static void main(String[] args) {
// TODO Auto-generated method stub
animal A=new animal("动物");
Cat B=new Cat("猫","black");
Dog C=new Dog("狗","yellow");
System.out.println(A instanceof animal);//从子类到父类 向上转型 输出 true
System.out.println(A instanceof Cat);//从父类到子类 向下转型 输出 false
animal a1=new Cat("旺财","白");
System.out.println(a1.getName());//只能获取父类的属性
if (a1 instanceof Cat) { //前面所初始化的a1参数列表与cat类构造方法参数匹配 所以为true
Cat demp=(Cat)a1; //强制转型
System.out.println(demp.getEyes_color());
}
}
}
运行结果:
true
false
旺财
白
2.多态方法
方法的动态绑定:在程序是运行期间判断对象变量所引用的对象的实际类型,根据其实际类型调用相应的方法。
方法的多态是基于方法覆盖和动态绑定机制的,具体调用父类还是子类的方法,不是由声明变量时的类型决定,而是由运行时动态绑定决定的。
public class MethodPolymorphismTest {
public static class animals{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public animals(String name){
this.name=name;
}
public String getBrak(){
return "叫声。。。";
}
}
public static class dog extends animals{
public dog(String name){
super(name);
}
private String furColor;
dog(String name,String furColor){
super(name);
this.furColor=furColor;
}
public String getBrak(){
return "狗叫。。。";
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
animals d1=new dog("小黑");
System.out.println(d1.getBrak());
}
}
运行结果:
狗叫。。。
3.多态参数
public class ParamPolymorphismTest {
public static class animals{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public animals(String name){
this.name=name;
}
public String getBrak(){
return "叫声。。。";
}
}
public static class dog extends animals{
public dog(String name){
super(name);
}
private String furColor;
public String getFurColor() {
return furColor;
}
public void setFurColor(String furColor) {
this.furColor = furColor;
}
dog(String name,String furColor){
super(name);
this.furColor=furColor;
}
public String getBrak(){
return "狗叫。。。";
}
}
public static class Lady{
private String name;
private animals pet; //使用父类对象 实例化时可以传入父类、也可以传入子类
Lady(String name,animals pet){
this.name=name;
this.pet=pet;
}
public void enjoy(){
System.out.println(name+"女士的宠物"+pet.getName()+"发出"+pet.getBrak());
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
dog d1=new dog("小黑","黑");
Lady l1=new Lady("张女士",d1);
l1.enjoy();
Lady l2=new Lady("小刘",new animals("zz"));
l2.enjoy();
}
}
运行结果:
张女士女士的宠物小黑发出狗叫。。。
小刘女士的宠物zz发出叫声。。。
在定义方法的时候哦尽量面向父类,而不要使用具体子类。
抽象类
抽象方法:没有方法主体的方法声明,用abstract关键字来声明;
包含抽象方法的类为抽象类,抽象类可以有具体属性,构造器和具体方法。
抽象类主要用来被继承。如果子类继承抽象类,没有覆盖父类的所有抽象方法,那子类也要声明为抽象类。
abstract class Shape //定义一个抽象类
{
private double weight,height;
Shape(double weight,double height){
this.weight=weight;
this.height=height;
}
public double getHeight() { //设置属性get方法
return height;
}
public double getWeight() {
return weight;
}
public abstract double getPerimeter();//返回周长
public abstract double getArea();//返回周长
}
public class Abstract_class_demo extends Shape {
public double r;
Abstract_class_demo(double weight, double height,double r) {
super(weight, height);
this.r=r;
// TODO Auto-generated constructor stub
}
public double getPerimeter() {
return (this.getHeight()+this.getWeight())*2;
}
public double getArea() {
return (this.getHeight())*(this.getWeight());
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Shape shape;
shape=new Abstract_class_demo(3,3,3.3);
System.out.println("周长:"+shape.getPerimeter()+'\n'+"面积:"+shape.getArea());
}
}
运行结果:
周长:12.0
面积:9.0
如果一个类包含抽象方法,那么它必须是抽象类;但抽象类中不一定由抽象方法。