一、使用继承
继承是面向对象语法的三大特征之一。继承可以降低代码编写的冗余度,提高编程的效率。
1、继承的作用
通过继承可以快速创建新的类,实现代码的重用,提高程序的可维护性,节省大量创建新类的时间,提高开发效率和开发质量。
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
class 父类{
... //成员变量、成员方法
}
class 子类 extends 父类{
... //类体
}
2、继承的基本实现
class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
class Student extends Person {
}
public class JiCheng {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("张三");
stu.setAge(20);
System.out.println("姓名是:"+stu.getName()+", 年龄是:"+stu.getAge());
}
}
当发生了类继承关系之后,子类可以直接继承父类的操作,可以实现代码的重用。子类最低也维持和父类相同的功能。子类也可以进行功能的扩充。
3、继承的底层本质
在《JAVA程序设计与应用开发》一书中提到其本质为子类继承父类后实例化子类对象的时候系统会首先实例化父类对象。通俗地讲就是先执行父类后执行子类
class Person {
public Person() {
System.out.println("1.Person类的对象产生");
}
}
class Student extends Person {
public Student() {
//super();
System.out.println("2.Student类的对象产生");
}
}
public class JiCheng3 {
public static void main(String[] args) {
new Student();
}
}
以上代码我们发现,没有任何一条语句调用父类构造方法。因此,子类对象实例化之前一定先实例化父类对象。
4、继承的优点
继承过来的字段和方法,可以像任何其他字段和方法一样被直接使用;
在子类中可以声明一个与父类中同名的新字段或静态方法,从而“隐藏”父类中的字段或方法;
可以在子类中声明一个在父类中没有的新字段和方法;
可以在子类中编写一个父类当中具有相同名的新实例方法,这称为“方法重写”或“方法覆盖”;
可以在子类中编写一个调用父类构造方法的子类构造方法,既可以隐式地实现,也可以通过使用关键字super来实现。
5、子类访问父类私有成员
子类继承其父类的所有public和protected成员,但不能继承其父类的private成员。那么如何在子类中访问到父类中的字段呢,我们可以在父类中提供用来访问其私有字段的public或protected方法,子类使用这些方法来访问相应的字段。例如:
class A{ //父类A
private int value=10; //声明一个私有变量value并赋值为10
public int getvalue() { //声明一个公有成员方法getvalue,返回value
return value;
}
}
class B extends A{ //A的子类B
}
public class myfirst {
public static void main(String[] args) {
B b=new B(); //创建子类B的一个实例对象
System.out.println("子类通过父类提供的公共接口访问A中的私有字段value:"+b.getvalue());
}
}
运行结果为:
子类通过父类提供的公共接口访问A中的私有字段value:10
6、注意
- 子类不能选择性继承父类;
- Java不支持多重继承,但一个类可以实现多个接口,从而克服单继承的缺点;
- 构造方法不会被子类继承,但可以从子类中调用父类的构造方法。成员的覆盖
在Java的多态特点中,子类继承父类的成员变量时,如果字面值不一致时。不是说子类没有继承父类的特性,而是子类将父类的特性覆盖了。这时将会使用子类的成员变量,而父类的成员变量将被保护起来。
//定义一个父类Fruit
public class Fruit {
String color="yellow";
String size="small";
//定义两个Default方法
String getFruitColor(){
return color;
}
String getFruitSize(){
return size;
}
}
//定义一个子类Apple
public class Apple extends Fruit {
String apple_color="green";
String apple_size="big";
String getFruitColor(){
return apple_color;
}
String getFruitSize(){
return apple_size;
}
public static void main(String[] args) {
Fruit f=new Apple();//创建一个Fruit类的Apple对象
System.out.println(f.getFruitColor());
System.out.println(f.getFruitSize());
}
}
此时输出的结果为:
green
big
Process finished with exit code 0
- 多态
多态是面向对象程序设计(OOP)的一个重要特征,指同一个实体同时具有多种形式,即同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
- 多态的好处
A.多态可以让我们不用关心某个对象到底具体是什么类型,就可以使用该对象的某些方法
B.提高了程序的可扩展性和可维护性
2、多态的使用
- 成员变量: 使用的是父类的
- 成员方法: 由于存在重写现象,所以使用的是子类的
- 静态成员: 随着类的加载而加载,谁调用就返回谁的
注意:前提条件为多态将自己看做父类类型
- 多态使用测试
package cn.tedu.oop2; /*本类用于测试多态成员的使用情况*/ public class TestDemo2 { public static void main(String[] args) { //7.创建纯纯的子类对象 Dog2 d = new Dog2(); System.out.println(d.sum);//20,子类自己的属性 d.eat();//小狗爱吃肉包子,子类自己的方法 //8.创建多态对象 /*口诀1:父类引用指向子类对象*/ /*口诀2:编译(保存)看左边,运行(效果)看右边*/ Animal2 a = new Dog2(); /*多态中,成员变量使用的是父类的*/ System.out.println(a.sum);//10 /*多态中,方法的声明使用的是父类的,方法体使用的是子类的*/ a.eat();//小狗爱吃肉包子 /*多态中,调用的静态方法是父类的,因为多态对象把自己看作是父类类型 * 直接使用父类中的静态资源*/ a.play();//没有提示,玩啥都行~ Animal2.play(); } } //1.创建父类 class Animal2{ //3.创建父类的成员变量 int sum = 10; //4.创建父类的普通方法 public void eat(){ System.out.println("吃啥都行~"); } //9.1定义父类的静态方法play public static void play(){ System.out.println("玩啥都行~"); } } //2.创建子类 class Dog2 extends Animal2{ //5.定义子类的成员变量 int sum = 20; //6.重写父类的方法 @Override public void eat(){ System.out.println("小狗爱吃肉包子"); } //9.2创建子类的静态方法play //@Override /*这不是一个重写的方法,只是恰巧在两个类中出现了一模一样的两个静态方法 * 静态方法属于类资源,只有一份,不存在重写的现象 * 在哪个类里定义,就作为哪个类的资源使用*/ public static void play(){ System.out.println("小狗喜欢玩皮球~"); } }
- 抽象类和接口
- 抽象类
-
抽象类 与 普通类
抽象类的 成员变量,成员函数,构造函数都与普通类一致。
除了:
抽象类有 abstract 修饰。
抽象类不可以实例化对象。
抽象类可以有抽象方法。
抽象方法不能有方法体,只能在非抽象子类中实现。
抽象方法
abstract 修饰的方法是抽象方法。抽象方法没有实现,需要在子类中实现。
public abstract void test();
抽象类可以没有抽象方法,但是有抽象方法的一定是抽象类。
- 接口
-
a.接口不能实例化对象。
b.接口没有构造函数。
c.接口中都是抽象方法。
d.接口不能包含成员变量,除了被 static final 修饰的变量。
e.接口被类实现,一个类可以实现多个接口。
3、注意
(1)一个类 只能继承一个抽象类,但是可以实现多个接口。
(2)抽象类中成员变量可以是各种类型的;接口中变量只能是 public static final 。
(3)抽象类中的非抽象方法 可以是 private default protected public;接口中只能是 default 的方法。非抽象方法有方法体。
注:此系列浅谈JAVA面向对象有所借鉴《Java程序设计与应用开发》一书以及网络资料,但实有理解,表达方式大同小异,如有偏差望指正!