java学习

第三周

课前问题

1.为什么说Java中的所有类都is-a Object?

在 Java 中,所有类都隐式地继承自 java.lang.Object 类。因此,可以说 Java 中的所有类都是 Object 类的子类或子类型。

Object 类是 Java 默认的根类或基类,它提供了一些通用的方法和功能,可以在所有对象上使用。这些方法包括 toString()equals()hashCode() 等。

当你在 Java 中定义一个类时,如果没有显式地指定一个类去继承,那么该类会自动继承 Object 类。这意味着,你可以在任何类中使用 Object 类中定义的方法。

2.在JDK文档中查找Object的toString方法。说一说,该方法有什么用?使用Eclipse查看Object的toString方法的代码,结合代码说说该代码的用途。

Object类是Java中所有类的超类,所以所有的Java对象都继承了toString方法。toString方法的目的是返回一个表示该对象的文本字符串。

使用Eclipse查看Object的toString方法的代码,可以看到如下代码:

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

该代码的主要用途是生成一个包含对象类名和哈希码的字符串。其中,getClass()方法返回对象的运行时类,getName()方法返回类的全名。hashCode()方法返回对象的哈希码。Integer.toHexString()方法将哈希码转换为十六进制字符串。

使用toString方法的主要目的是方便调试和打印对象时的可读性。通过重写toString方法,可以返回对象特定的描述信息,方便开发者阅读和理解对象的状态和内容。通常,在使用System.out.println或日志打印对象时,会隐式调用对象的toString方法来获取对象的字符串表示。因此,重写toString方法可以提高代码的可读性和调试的便捷性。

3.在Eclipse中查看Object的equals方法的代码,说说equals的用途。该方法被什么修饰符修饰,意味着什么?什么时候需要覆盖equals方法?结合String类的equals方法说说覆盖如何体现子类特有的特性?

在Eclipse中查看Object的equals方法的代码,可以通过在Eclipse中打开源代码视图,导航到Object类,然后找到equals方法。

Object的equals方法的代码如下:

public boolean equals(Object obj) {
    return (this == obj);
}

equals方法被public修饰符修饰,意味着该方法可以被其他类访问。public修饰符表示该方法是公共的,可以被任何其他类使用。

equals方法的主要用途是比较对象的内容是否相等。默认的equals方法实现是通过比较对象的引用是否相等,即判断两个对象是否为同一个实例。

需要覆盖equals方法的情况通常是在需要比较对象内容的情况下。当我们想要判断两个对象是否具有相同的属性和状态时,需要重写equals方法。例如,我们自定义了一个类,并且希望根据该类的属性进行对象比较,就需要覆盖equals方法以实现自定义的比较逻辑。

以String类的equals方法为例,String类覆盖了Object类的equals方法来实现字符串内容的比较。String类的equals方法比较的是两个字符串对象的字符序列是否完全一致,而不仅仅是比较引用。这是因为字符串对象的内容是有意义的,所以在比较字符串时,需要考虑对象内容的一致性。

覆盖equals方法时,需要注意遵循一些规则,如:

  • 对称性:如果a.equals(b)返回true,那么b.equals(a)也应该返回true。
  • 自反性:a.equals(a)应该返回true。
  • 传递性:如果a.equals(b)返回true,且b.equals©返回true,那么a.equals©也应该返回true。
  • 一致性:对象的比较结果应该在对象状态没有变化时保持不变。

通过覆盖equals方法,子类可以根据自身特有的特性实现自定义的对象比较逻辑。这允许子类在比较对象时,考虑到其自身的属性和状态,从而更加准确地比较对象的相等性。

4.如果在子类中想要复用父类的代码,要怎么办?

如果在子类中想要复用父类的代码,可以通过继承和使用super关键字来实现。

继承是面向对象编程中的一个重要概念,它允许子类继承父类的属性和方法。在Java中,使用extends关键字来实现继承。子类可以继承父类的非私有属性和方法。

对于需要复用的父类代码,可以将其放在父类中的方法中。子类可以通过调用super关键字,来调用父类中的方法或构造函数。

具体步骤如下:

  1. 子类声明继承父类,使用extends关键字。例如,class ChildClass extends ParentClass {}
  2. 在子类中,使用super关键字调用父类的方法或构造函数。例如,super.methodName()super()

通过继承和super关键字,子类可以复用父类的代码,并且在此基础上扩展和定制自己特有的功能。这样可以避免重复编写相同的代码,提高代码的可重用性和扩展性。

需要注意的是,父类中的方法或构造函数必须具有适当的可见性(public或protected),以便子类可以访问和复用。私有(private)的方法或构造函数是不可继承和复用的。

5.继承是复用代码的唯一方式吗?

  1. 组合:通过将一个类的实例作为另一个类的成员变量,实现代码的复用。这样可以在新类中使用已有类的功能。

  2. 接口实现:通过实现接口,在新类中实现接口定义的方法,从而复用接口中的代码。多个类可以通过实现同一个接口来共享同一套方法逻辑。

  3. 委托:委托是指在一个类中调用另一个类的方法来完成一项功能。通过在新类中将调用委托给已有类,实现代码复用。

PTA作业

6-1 jmu-Java-03面向对象基础-覆盖与toString

Person类,Company类,Employee类。
其中Employee类继承自Person类,属性为:

private Company company;
private double salary;

现在要求编写Employee类的toString方法,返回的字符串格式为:父类的toString-company的toString-salary

public String toString()
{
    return super.toString()+"-"+company.toString()+"-"+salary;
}

6-2 jmu-Java-03面向对象基础-Object

输入整数n,创建n个对象,放入同一个数组中。

如果输入c,则new Computer(); //注意:Computer是系统中已有的类,无需自己编写

如果输入d,则根据随后的输入创建Double类型对象。

如果输入i,则根据随后的输入创建Integer类型对象。

如果输入s,则根据随后的输入创建String类型对象。

如果不是以上这些输入,则不创建对象,而是将null存入数组相应位置。

最后倒序输出数组中的所有对象,如果数组中相应位置的元素为null则不输出。

int n=sc.nextInt();
Object[] a=new Object[n];
for(int i=0;i<n;i++)
{
    String op=sc.next();
    if(op.equals("c")) a[i]=new Computer();
    else if(op.equals("d")) a[i]=new Double(sc.nextDouble());
    else if(op.equals("i")) a[i]=new Integer(sc.nextInt());
    else if(op.equals("s")) a[i]=new String(sc.next());
    else a[i]=null;
}
for(int i=n-1;i>=0;i--)
{
    if((a[i] instanceof String)||(a[i] instanceof Integer)||(a[i] instanceof Double)||(a[i] instanceof Computer))
    {
        System.out.println(a[i].toString());
    }
}

6-3(选做) jmu-Java-03面向对象基础-覆盖与equals

Person类,Company类,Employee类。

其中Employee类继承自Person类,属性为:

private Company company;
private double salary;

现在要求覆盖Employee类的equals方法,判定两个Employee对象是否相等,请见如下判断方法:

其继承自父类Person的属性值都相等,其company属性对象equals返回true,且其salary也相等。

salarydouble型,比较时,使用DecimalFormat df = new DecimalFormat("#.##");使salary保留两位小数,然后再进行比较。

注意:要考虑companynull的情况。

public boolean equals(Object obj)
{
    if(this==obj) return true;
    if(!(obj instanceof Employee)) return false;
    Employee other=(Employee) obj;
    if(!super.equals(other)) return false;
    if(this.company==null)
    {
        if(other.company!=null) return false;
    }
    else if(!this.company.equals(other.company))
    {
        return false;
    }
    DecimalFormat df=new DecimalFormat("#.##");
    String thisSalary=df.format(this.salary);
    String otherSalary=df.format(other.salary);
    return thisSalary.equals(otherSalary);
}

6-4(选做) jmu-Java-03面向对象基础-clone方法、标识接口、深拷贝

class Car implements Cloneable
{
    private String name;
    private CarDriver driver;
    private int[] scores;
    public Car() {}
    public void setName(String name)
    {
        this.name=name;
    }
    public void setDriver(CarDriver driver)
    {
        this.driver=driver;
    }
    public void setScores(int[] scores)
    {
        this.scores=scores;
    }
    public String getName()
    {
        return name;
    }
    public CarDriver getDriver()
    {
        return driver;
    }
    public int[] getScores()
    {
        return scores;
    }
    public String toString()
    {
        return "Car [name=" + name + ", driver=" + driver + ", scores=" + Arrays.toString(scores) + "]";
    }
    public Car clone() throws CloneNotSupportedException
    {
        Car car=new Car();
        CarDriver cd=new CarDriver();
        if(driver==null) {cd=null;}
        else {cd.setName(driver.getName());}
        car.setDriver(cd);
        car.setName(name);
        if(scores == null) car.setScores(null);
        else
        {
            int[] arr=Arrays.copyOf(scores,scores.length);
            car.setScores(arr);
        }
        return car;
    }
}

7-1 jmu-Java-03面向对象基础-05-覆盖

Java每个对象都继承自Object,都有equalstoString等方法。
现在需要定义PersonOverride类并覆盖其toStringequals方法。

  1. 新建PersonOverride
    a. 属性:String nameint ageboolean gender,所有的变量必须为私有(private)。

b. 有参构造方法,参数为name, age, gender

c. 无参构造方法,使用this(name, age,gender)调用有参构造方法。参数值分别为"default",1,true

d.toString()方法返回格式为:name-age-gender

e. equals方法需比较nameagegender,这三者内容都相同,才返回true.

  1. main方法
    2.1 输入n1,使用无参构造方法创建n1个对象,放入数组persons1
    2.2 输入n2,然后指定name age gender。每创建一个对象都使用equals方法比较该对象是否已经在数组中存在,如果不存在,才将该对象放入数组persons2。
    2.3 输出persons1数组中的所有对象
    2.4 输出persons2数组中的所有对象
    2.5 输出persons2中实际包含的对象的数量
    2.5 使用System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));输出PersonOverride的所有构造方法。
import java.math.BigDecimal;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner cin=new Scanner(System.in);
        int n1=cin.nextInt();
        List<PersonOverride> PersonOverride1=new ArrayList<>();
        List<PersonOverride> PersonOverride2=new ArrayList<>();
        for(int i=0;i<n1;i++)
        {
            PersonOverride tmp=new PersonOverride();
            PersonOverride1.add(tmp);
        }
        int n2=cin.nextInt();
        for(int i=0;i<n2;i++)
        {
            PersonOverride tmp=new PersonOverride(cin.next(),cin.nextInt(),cin.nextBoolean());
            boolean ok=true;
            for(int j=0;j<PersonOverride2.size();j++)
            {
                PersonOverride PersonOverride=PersonOverride2.get(j);
                if(PersonOverride.equals(tmp)==true) ok=false;
            }
            if(ok==true) PersonOverride2.add(tmp);
        }
        for(PersonOverride PersonOverride:PersonOverride1)
        {
            System.out.println(PersonOverride);
        }
        for(PersonOverride PersonOverride:PersonOverride2)
        {
            System.out.println(PersonOverride);
        }
        System.out.println(PersonOverride2.size());
        System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));
    }
}
class PersonOverride
{
    private String name;
    private int age;
    private boolean gender;
    public PersonOverride()
    {
        this("default",1,true);
    }
    public PersonOverride(String name,int age,boolean gender)
    {
        this.name=name;
        this.age=age;
        this.gender=gender;
    }
    public String toString()
    {
        return this.name+"-"+this.age+"-"+this.gender;
    }
    public boolean equals(Object obj)
    {
        if(this==obj)
        {
            return true;
        }
        if(obj==null||getClass()!=obj.getClass())
        {
            return false;
        }
        PersonOverride other = (PersonOverride) obj;
        boolean equalsName=Objects.equals(this.name,other.name);
        boolean equalsAge=this.age==other.age;
        boolean equalsGender=this.gender==other.gender;
        return equalsName&&equalsAge&&equalsGender;
    }
}

7-2 jmu-Java-03面向对象基础-04-形状-继承

1.定义抽象类Shape
属性:不可变静态常量double PI,值为3.14
抽象方法:public double getPerimeter(),public double getArea()

2.RectangleCircle类均继承自Shape类。
Rectangle类(属性:int width,length)、Circle类(属性:int radius)。
带参构造方法为Rectangle(int width,int length),Circle(int radius)。
toString方法(Eclipse自动生成)

3.编写double sumAllArea方法计算并返回传入的形状数组中所有对象的面积和与double sumAllPerimeter方法计算并返回传入的形状数组中所有对象的周长和。

4.main方法
4.1 输入整型值n,然后建立n个不同的形状。如果输入rect,则依次输入宽、长。如果输入cir,则输入半径。
4.2 然后输出所有的形状的周长之和,面积之和。并将所有的形状信息以样例的格式输出。
4.3 最后输出每个形状的类型与父类型.使用类似shape.getClass() //获得类型, shape.getClass().getSuperclass()//获得父类型;

import java.math.BigDecimal;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner cin=new Scanner(System.in);
        int n=cin.nextInt();
        List<Shape> shapes=new ArrayList<>();
        for(int i=0;i<n;i++)
        {
            String op=cin.next();
            if(op.equals("rect"))
            {
                Rectangle rect=new Rectangle(cin.nextInt(),cin.nextInt());
                shapes.add(rect);
                Shape.sumArea(rect);
                Shape.sumPerimeter(rect);
            }
            else
            {
                Circle cir=new Circle(cin.nextInt());
                shapes.add(cir);
                Shape.sumArea(cir);
                Shape.sumPerimeter(cir);
            }
        }
        System.out.println(Shape.getAllPerimeter());
        System.out.println(Shape.getAllArea());
        System.out.println(shapes.toString());
        for(Shape shape:shapes)
        {
            System.out.print(shape.getClass()+",");
            System.out.println(shape.getClass().getSuperclass());
        }
    }
}
abstract class Shape
{
    final double PI=3.14;
    private static double area=0.0;
    private static double perimeter=0.0;
    static double getAllPerimeter()
    {
        return perimeter;
    }
    static double getAllArea()
    {
        return area;
    }
    static void sumArea(Rectangle rect)
    {
        area+=rect.getArea();
    }
    static void sumArea(Circle cir)
    {
        area+=cir.getArea();
    }
    static void sumPerimeter(Rectangle rect)
    {
        perimeter+=rect.getPerimeter();
    }
    static void sumPerimeter(Circle cir)
    {
        perimeter+=cir.getPerimeter();
    }
}
class Rectangle extends Shape
{
    private int width,length;
    public Rectangle(int width,int length)
    {
        this.width=width;
        this.length=length;
    }
    public String toString() {
        return "Rectangle [width=" + width + ", length=" + length + "]";
    }
    public double getArea()
    {
        return this.width*this.length;
    }
    public double getPerimeter()
    {
        return 2.0*(this.width+this.length);
    }
}
class Circle extends Shape
{
    private int radius;
    public Circle(int radius)
    {
        this.radius=radius;
    }
    public String toString() {
        return "Circle [radius=" + radius + "]";
    }
    public double getArea()
    {
        return radius*radius*PI;
    }
    public double getPerimeter()
    {
        return radius*2.0*PI;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值