继承、多态、抽象类与接口
继承、多态、抽象类与接口
继承和多态是面向对象开发中非常重要的一组概念。继承和多态使用得当,整个程序的架构将变得非常有弹性,同时可以减少写代码的冗余性。继承机制下,用户可以复用一些定义好的类,减少重复代码的编写。多态机制下,用户可以动态调整对象的调用,降低对象之间的依存关系。为了优化继承与多态,一些类除了可继承父类,还需要使用接口的形式。java 中的类可以同时实现多个接口,接口被用来建立类与类之间关联的标准。正因为具有这些灵活、高效的机制,java 语言才更具有生命力。
类的继承
继承在面向对象开发思想中是一个非常重要的概念,它使整个程序架构具有一定的弹性。在程序中复用一些已经定义完善的类,不仅可以减少软件开发周期,也可以提高软件的可维护性和可拓展性。
在 java 中,一个类继承另一个类需要使用关键字 extends,关键字 extends 的使用方法如下:
class Child extends Parent{}
因为 java 只支持单继承,即一个类只能有一个父类,所以类似下面的代码是错误的:
class Child extends Parent1, Parent2 {}
子类在继承父类之后,创建子类对象的同时也会调用父类的构造方法。
父类 Parent 和子类 Child 都各自有一个无参的构造方法,在 main() 方法中创建子类对象时,java虚拟机会先执行父类的构造方法,然后再执行子类的构造方法。
class Parent {
public Parent() {
System.out.println("调用父类的构造方法");
}
class Child extends Parent {
public Child() {
System.out.println("调用子类的构造方法");
}
public class Demo {
public static void main(String[] args) {
new Child();
}
}
}
}
运行结果如下:
调用父类构造方法
调用子类构造方法
Object 类
在 Object 类中,主要包括 clone() finalize() equals() toString() 等方法。由于所有的类都是 Object 类的子类,所以任何类都可以重写 Object 类中的方法。
注意:Object 类中的 getClass90 notify90 notifyAll() wait() 等方法不能被重写,应为这些方法被定义为 final 类型。
getClass() 方法
getClass() 方法是 Object 类定义的方法,他会返回对象执行时的 Class 实例,然后使用此实例调用 getName() 方法可以取得类的名称。语法如下:
getClass().getName();
可以将 getClass() 方法与 toString() 方法联合使用。
toString() 方法
toString() 方法的功能是将一个对象返回为字符串形式,他会返回一个 String 实例。在实际的应用中通常从写 toString() 方法,为对象提供一个特定的输出模式。当这个类转换为字符串或与字符串链接时,将自动调用重新的 toString() 方法。
创建 Student 类,重写toString() 方法,是该类的对象可以自定义输出自己的姓名和年龄。
public class Student {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "我叫" + name + ",今年" + age + "岁。";
}
public static void main(String[] args) {
Student s1 = new Student("张三", 16);
System.out.println(s1);
Student s1 = new Student("李四", 19);
System.out.println(s2);
}
}
运行结果:
我叫张三,今年16岁。
我叫李四,今年19岁。
equals() 方法
在 java 中,有两种比较对象的方式,分别为 “ == ” 运算符和 equals() 方法。两者的区别在于: “==” 比较的是两个对象引用内存地址是否相等,而 equals() 方法比较的是两个对象的实际内容。
例如下面的实例,根据身份证号和姓名两个属性,重写 equals() 方法,仅以身份证号码作为区别条件。创建 n 个 people 对象,用 equals() 方法和 “==” 运算符来判断是否存在多个对象代表同一个人。
public class People {
int id;
String name;
public People(int id, String name) {
this.id = id;
this.name = name;
}
public boolean equals(Object obj) {
if (this == obj) {return true;}
if (obj == null) {return false;}
if (getClass() != obj.getClass()) {return false;}
People other = (People) obj;
if (id != other.id) {return false;}
return true;
}
public String toString() {
return name;
}
public static void main(String[] args) {
People P1 = new People(220, "tom");
People P1 = new People(220, "汤姆");
People P1 = new People(330, "张三");
Object o = new Object();
System.out.print(p1 + "与" + p2 + "是否为同一个人:");
System.out.print("equals() 方法的结果:" + p1.equals(p2));
System.out.print("== 运算符的结果:" + (p1 == p2));
System.out.println();
System.out.print(p1 + "与" + p3 + "是否为同一个人:");
System.out.print(p1.equals(p3));
System.out.print(p1 + "与" + o + "是否为同一个人?");
System.out.print(pq.equals(o));
}
}
运行结果:
tom 与汤姆是否为同一个人?
equals() 方法的结果:true
== 运算符的结果为:false
tom 与张三是否为用一个人?false
tom 与 java.lang.Object@48cf768c 是否为同一个人?false
从这个结果看出,tom 和汤姆虽然名字相同,但是两者的身份证号码相同,所以 equals() 方法判断除了这两个对象实际上是同一个,而 “==” 预算算符无法做出有效的判断,如果两个对象的身份证号不同,或者两个对象类型都不同, equals() 方法就会认为两者不是同一个人。
对象类型的转换
对象类型的转换在 java 编程中经常遇到,主要包括向上转型与向下转型操作。
向上转型
向上转型可以被理解为将子类类型的对象转换为父类类型的对象,即吧子类类型的对象直接赋值给父类类型的对象,进而实现按照父类描述子类的效果。
使用向上转型模拟如下场景:这里有一个人,他叫 tom ,他是一名牧师。
class People {}
class Tracher extends People {}
public class Dome {
public static void main(String[] args) {
People tom = new Teacher();
}
}
浙公网安备 33010602011771号