/*抽象设计和抽象方法
使用abstract修饰且没有方法体的方法,称为抽象方法
*/
/*
//图形
class Graph
{
    public Double getAres()
    {
        return 0.0;
    }
}

//圆
class Circle extends Graph
{
    private Integer r;

    Circle(Integer r)
    {
        this.r = r;
    }
    //求面积
    public Double getAres()
    {
        return 3.14 * r * r;
    }
}

//矩形
class Rectangles extends Graph
{
    private Integer witdh;
    private Integer beight;
    
    Rectangles(Integer witdh, Integer beight)
    {
        this.witdh = witdh;
        this.beight = beight;
    }
    //求面积
    public Double getAres()
    {
        return witdh.doubleValue() * beight.doubleValue();
    }
}

//三角形
class Triangle extends Graph
{
    private Integer a;
    private Integer b;
    private Integer c;

    Triangle(Integer a, Integer b, Integer c)
    {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    //在这个类中先不定义getAres方法,也就是说不覆盖父类求面积的方法
}

class AbstractDemo 
{
    public static void main(String[] args) 
    {
        //求圆的面积
        System.out.println(new Circle(10).getAres());

        //求矩形的面积
        System.out.println(new Rectangles(5,7).getAres());

        //求三角形的面积
        System.out.println(new Triangle(3,4,5).getAres());
    }
}
/*
/*
上诉设计的问题:
1、每一个图形都有面积,所以在Graph类中定义求面积的方法
但是,不同的具体图形求面积的算法是不一样的,也就是说每个子类
都必须去覆盖getAres方法,如果不覆盖应该语法报错,但是目前没有报错
2、在图形类中定义了getAres方法,该方法不应该存在方法体,因为不同图形
子类求面积算法不一样,父类真不知道该怎么写,所以应该提供无方法体

3、要解决这个问题,就得要用抽象方法来解决(没有方法体,必须要求子类覆盖)
*/


//--------------------------抽象方法登场!!!----------------------------------
/*
使用abstract修饰且没有方法体的方法,称为抽象方法,他是一个修饰符
*/
//图形
abstract class Graph //抽象类(不能创建对象,即使创建出抽象类对象也没有意义,抽象类必须要有子类)
{
    abstract public Double getAres(); //抽象方法(无方法体,不存在任何功能性代码,必须要被子类覆盖这个方法,有子类去完成功能,如子类不覆盖则编译报错)
    
    //抽象类可以存在普通方法,用于给子类调用
    public void doWork()
    {
        System.out.println("hello");
    }
}

//圆
class Circle extends Graph
{
    private Integer r;

    Circle(Integer r)
    {
        this.r = r;
    }
    //求面积
    public Double getAres()
    {
        return 3.14 * r * r;
    }
}

//矩形
class Rectangles extends Graph
{
    private Integer witdh;
    private Integer beight;
    
    Rectangles(Integer witdh, Integer beight)
    {
        this.witdh = witdh;
        this.beight = beight;
    }
    //求面积
    public Double getAres()
    {
        return witdh.doubleValue() * beight.doubleValue();
    }
}

//三角形
class Triangle extends Graph
{
    private Integer a;
    private Integer b;
    private Integer c;

    Triangle(Integer a, Integer b, Integer c)
    {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public Double getAres()
    {
        Double p = (a+b+c)/2.0;
        return Math.sqrt(p*(p-a)*(p-b)*(p-c));
    }
}

class AbstractDemo 
{
    public static void main(String[] args) 
    {
        //求圆的面积
        System.out.println(new Circle(10).getAres());

        //求矩形的面积
        System.out.println(new Rectangles(5,7).getAres());

        //求三角形的面积
        System.out.println(new Triangle(3,4,5).getAres());
        new Triangle(3,4,5).doWork(); //调用抽象类中的普通方法

        //不能创建抽象类对象
        //Graph a = new Graph();
    }
}