重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分? 方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。 重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载; 重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问, 不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。抽象类(abstract class)和接口(interface)有什么异同?
抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。 一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现, 否则该类仍然需要被声明为抽象类。接口比抽象类更加抽象,因为抽象类中可以定义构造器, 可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法。 抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。 抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。 有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?
Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。 而通常的内部类需要在外部类实例化后才能实例化,其语法看起来挺诡异的,如下所示。 /** * 扑克类(一副扑克) * @author 骆昊 * */ public class Poker { private static String[] suites = {"黑桃", "红桃", "草花", "方块"}; private static int[] faces = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; private Card[] cards; /** * 构造器 * */ public Poker() { cards = new Card[52]; for(int i = 0; i < suites.length; i++) { for(int j = 0; j < faces.length; j++) { cards[i * 13 + j] = new Card(suites[i], faces[j]); } } } /** * 洗牌 (随机乱序) * */ public void shuffle() { for(int i = 0, len = cards.length; i < len; i++) { int index = (int) (Math.random() * len); Card temp = cards[index]; cards[index] = cards[i]; cards[i] = temp; } } /** * 发牌 * @param index 发牌的位置 * */ public Card deal(int index) { return cards[index]; } /** * 卡片类(一张扑克) * [内部类] * @author 骆昊 * */ public class Card { private String suite; // 花色 private int face; // 点数 public Card(String suite, int face) { this.suite = suite; this.face = face; } @Override public String toString() { String faceStr = ""; switch(face) { case 1: faceStr = "A"; break; case 11: faceStr = "J"; break; case 12: faceStr = "Q"; break; case 13: faceStr = "K"; break; default: faceStr = String.valueOf(face); } return suite + faceStr; } } }测试代码
class PokerTest { public static void main(String[] args) { Poker poker = new Poker(); poker.shuffle(); // 洗牌 Poker.Card c1 = poker.deal(0); // 发第一张牌 // 对于非静态内部类Card // 只有通过其外部类Poker对象才能创建Card对象 Poker.Card c2 = poker.new Card("红心", 1); // 自己创建一张牌 System.out.println(c1); // 洗牌后的第一张 System.out.println(c2); // 打印: 红心A } }