Java基础: 面向对象---类的继承

本文详细介绍了Java中的类继承概念,包括基础概念如父类、子类、重写方法,以及如何通过继承实现代码复用和多态。文章通过实例解释了如何使用super关键字,展示了如何在子类中重写父类的方法,并讨论了构造方法的使用。此外,文章还探讨了继承的细节,如静态绑定、重载与重写的选择规则,以及类型转换和protected权限。最后,文章指出继承是把双刃剑,可能导致封装性的破坏,并提出了避免继承破坏封装的建议,如使用final关键字、优先考虑组合和正确使用继承的方法。
摘要由CSDN通过智能技术生成

上一章,我们谈到了如何将现实中的概念映射为程序中的概念,我们谈了类以及类之间的组合,现实中的概念间还有一种非常重要的关系,就是分类。分类有个根,然后向下不断细化,形成一个层次分类体系。这种例子是非常多的:

1)在自然世界中,生物有动物和植物,动物有不同的科目,食肉动物、食草动物、杂食动物等,食肉动物有狼、狗、虎等,这些又分为不同的品种 。

2)打开电商网站,在显著位置一般都有分类列表,比如家用电器、服装,服装有女装、男装,男装有衬衫、牛仔裤等 …

计算机程序经常使用类之间的继承关系来表示对象之间的分类关系。在继承关系中,有父类子类,比如动物类Animal和狗类Dog,Animal是父类,Dog是子类。父类也叫基类,子类也叫派生类,父类子类是相对的,一个类B可能是类A的子类,是类C的父类。

之所以叫继承,是因为子类继承了父类的属性和行为,父类有的属性和行为子类都有但子类可以增加子类特有的属性和行为,某些父类有的行为,子类的实现方式可能与父类也不完全一样。

使用继承一方面可以复用代码,公共的属性和行为可以放到父类中,而子类只需要关注子类特有的就可以了;另一方面,不同子类的对象可以更为方便的被统一处理。

本问详细学习继承。我们先介绍继承的基本概念,然后详述继承的一些细节,理解了继承的用法之后,我们谈论继承的注意事项,解释为什么说继承是把双刃剑,以及如何正确地使用继承。

#一.基础概念
##1.根父类Object

在Java中,所有类都有一个父类,即使没有声明父类,也有一个隐含的父类,这个父类叫Object。Object没有定义属性,但定义了一些方法,如下图所示:
这里写图片描述

本节我们会介绍toString()方法,其他方法我们会在后续章节中逐步介绍。toString()方法的目的是返回一个对象的文本描述,这个方法可以直接被所有类使用。

比如说,对于我们之前介绍的Point类,可以这样使用toString方法:

Point p = new Point(2,3);
System.out.println(p.toString());

输出类似这样:

Point@76f9aa66

这是什么意思呢?@之前是类名,@之后的内容是什么呢?我们来看下toString的代码:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

getClass().getName()返回当前对象的类名,hashCode()返回一个对象的哈希值,哈希我们会在后续章节中介绍,这里可以理解为是一个整数,这个整数默认情况下,通常是对象的内存地址值,Integer.toHexString(hashCode())返回这个哈希值的shiliu进制表示。

为什么要这么写呢?写类名是可以理解的,表示对象的类型,而写哈希值则是不得已的,因为Object类并不知道具体对象的属性,不知道怎么用文本描述,但又需要区分不同对象,只能是写一个哈希值。

但子类是知道自己的属性的,子类可以重写父类的方法,以反映自己的不同实现。所谓重写,就是定义和父类一样的方法,并重新实现。

##2.方法重写

上一节,我们介绍了一些图形处理类,其中有Point类,这次我们重写了toString()方法。代码如下(Point.class):

public class Point {

    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
    
    @Override
    public String toString() {
        return "(" + x + "," + y + ")";
    }

}

toString方法前面有一个 @Override,这表示toString这个方法是重写的父类的方法(当然,也可以是父类的父类),重写后的方法返回Point的x和y坐标的值。重写后,将调用子类的实现。比如,如下代码的输出就变成了:(2,3)

Point p = new Point(2,3);
System.out.println(p.toString());

##3.图形类继承体系

接下来,我们以一些图形处理中的例子来进一步解释,先来看幅图:

这里写图片描述

这都是一些基本的图形,图形有线、正方形、三角形、圆形等,图形有不同的颜色。接下来,我们定义以下类来说明关于继承的一些概念:

  • 父类Shape,表示图形。
  • 类Circle,表示圆。
  • 类Line,表示直线。
  • 类ArrowLine,表示带箭头的直线,

1.图形
所有图形(Shape)都有一个表示颜色的属性,有一个表示绘制的方法,代码如下(Shape.class):

public class Shape {
	
	private static final String DEFAULT_COLOR = "black";
	
	private String color;
	
	public Shape() {
		this(DEFAULT_COLOR);
	}

	public Shape(String color) {
		this.color = color;
	}
	
	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
	
	public void draw(){
		System.out.println("draw shape");
	}
}

以上代码基本没什么可解释的,实例变量color表示颜色,draw方法表示绘制,我们不会写实际的绘制代码,主要是演示继承关系。

2.圆
圆(Circle)继承自Shape,但包括了额外的属性,中心点和半径,以及额外的方法area,用于计算面积,另外,重写了draw方法,代码如下:

public class Circle extends Shape {
    //中心点
    private Point center;

    //半径
    private double r;

    public Circle(Point center, double r) {
        this.center = center;
        this.r = r;
    }

    @Override
    public void draw() {
        System.out.println("draw circle at "
                + center.toString() + " with r " + r
                + ", using color : " + getColor());
    }

    public double area() {
        return Math.PI * r * r;
    }

}

说明:

  1. Java使用extends关键字标明继承关系,一个类最多只能有一个父类;
    2)子类不能直接访问父类的私有属性和方法,比如,在Circle中,不能直接访问shape的私有实例变量color;
    3)除了私有的外,子类继承了父类的其他属性和方法,比如,在Circle的draw方法中,可以直接调用getColor()方法。

我们来验证一下。代码如下(chapter_4Activity.class):

Point center = new Point(2,3);
//创建圆,赋值给circle
Circle circle = new Circle(center,2);
//调用draw方法,会执行Circle的draw方法
circle.draw();
//输出圆面积
System.out.println(circle.area());

程序的输出为:

draw circle at (2,3) with r 2.0, using color : black
12.566370614359172

这里比较奇怪的是,co

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值