有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

数组在java中类名是唯一更改的情况下,我可以使用继承吗?

我有重复的代码,其中代码中唯一的区别是类名及其传入的参数。 有没有办法重用这段代码

public void addToStaffList(Staff staff)
{
    if(this.staffList == null)
    {
        this.staffList = new Staff[]{staff};
        return;
    }
    if(!isThisStaffAlreadyListed(staff))
    {
        for(int i = 0; i < this.getStaffList().length; i++)
        { // first fill any empty array index
            if(this.getStaffList()[i] == null)
            {
                this.getStaffList()[i] = staff;
                return;
            }
        }
    }
    if(!isThisStaffAlreadyListed(staff))
    {
        int length = this.getStaffList().length;
        length++;
        Staff[] newStaffList = new Staff[length];
        for(int i = 0; i < this.getStaffList().length; i++)
        { // add staff to extended array with bigger index
            newStaffList[i] = this.getStaffList()[i];
        }
        newStaffList[newStaffList.length-1] = staff;
        this.staffList = newStaffList;
    }
}

这和……一样

public void addToRoomsList(Room room)
{
    if(this.roomsList == null)
    {
        this.roomsList = new Room[]{room};
        return;
    }
    if(!isThisRoomAlreadyListed(room))
    {
        for(int i = 0; i < this.getRoomsList().length; i++)
        { // first fill any empty array index
            if(this.getRoomsList()[i] == null)
            {
                this.getRoomsList()[i] = room;
                return;
            }
        }
    }
    if(!isThisRoomAlreadyListed(room))
    {
        int length = this.getRoomsList().length;
        length++;
        Room[] newRoomsList = new Room[length];
        for(int i = 0; i < this.getRoomsList().length; i++)
        { // add room to extended array with bigger index
            newRoomsList[i] = this.getRoomsList()[i];
        }
        newRoomsList[newRoomsList.length-1] = room;
        this.roomsList = newRoomsList;
    }
}

这些代码块的唯一区别是类名“Staff”和“Room”,还有参数变量“Staff”和“Room”。 即使在这些代码块中,也有更多重复的代码块,如isThisStaffAlreadyListed()isThisRoomAlreadyListed(),它们都有相同的代码块,只是类名发生了变化。 是否有一种方法可以通过某种方式传入类名及其参数来重用此代码


共 (2) 个答案

  1. # 1 楼答案

    大部分代码在数组中寻找一个开口,如果没有足够的空间,则将数组扩展一个元素

    如果您仅限于使用数组,重用代码的一种方法是创建一个扩展数组的通用帮助器方法,如下所示:

    public <T> T[] fitOrExpand(T[] a, T item, Class<T> type) {
        if (a == null) {
            T[] res = (T[])Array.newInstance(type, 1);
            res[0] = item;
            return res;
        }
        for (int i = 0 ; i != a.length ; i++) {
            if (a[i] == null) {
                a[i] = item;
                return a;
            }
        }
        T[] res = (T[])Array.newInstance(type, a.length+1);
        System.arraycopy(a, 0, res, 0, a.length);
        res[res.length-1] = item;
        return res;
    }
    

    您需要导入java.lang.reflect.Array才能编译它

    这几乎就是您的代码,只有三个例外:

    • 它假定房间或员工未列出。你必须单独检查
    • 它在代码中使用泛型类型T而不是特定类型,并且
    • 它使用^{}而不是第二个循环

    使用此方法,您可以像这样重写这两种方法:

    public void addToStaffList(Staff staff) {
        if(isThisStaffAlreadyListed(staff)) return;
        this.staffList == fitOrExpand(this.staffList, staff, Staff.class);
    }
    
    public void addToRoomsList(Room room) {
        if(isThisRoomAlreadyListed(room)) return;
        this.roomsList == fitOrExpand(this.roomsList, room, Room.class);
    }
    

    如果你可以使用^{,你可以进一步简化:如果你像这样声明你的staffListroomList

    List<Room> roomList = new ArrayList<Room>();
    List<Staff> staffList = new ArrayList<Staff>();
    

    您的助手方法如下所示:

    static <T> void fitOrExpand(List<T> list, T item) {
        // No null checking of the entire list is necessary,
        // because we created an empty list.
        // Go straight to null-checking elements:
        for (int i = 0 ; i != list.size() ; i++) {
            if (list.get(i) == null) {
                list.put(i, item);
                return;
            }
        }
        list.add(item);
    }
    

    这两个电话如下所示:

    public void addToStaffList(Staff staff) {
        if(isThisStaffAlreadyListed(staff)) return;
        fitOrExpand(this.staffList, staff);
    }
    
    public void addToRoomsList(Room room) {
        if(isThisRoomAlreadyListed(room)) return;
        fitOrExpand(this.roomsList, room);
    }
    
  2. # 2 楼答案

    你要找的东西名为generics。你的代码可能看起来像

    abstract class MyList<T> {
        public int size() {...}
        protected void addToList(T elem) {
            // insert your common code here
            // and use T instead of Staff/Room
        }
    }
    
    class StuffList extends MyList<Stuff> {
       public void addStuffToList(Stuff stuff) {addToList(stuff);}
    }
    

    或者

    class MyList<T> {
        public int size() {...}
        protected void addToList(T elem) {...}
    }
    
    class StuffList {
       private MyList<Stuff> list = new MyList<>();
       public void addStuffToList(Stuff stuff) {list.addToList(stuff);}
       public int size() { list.size(); }
    }