一、继承
1、为什么要使用继承?
使用继承优化后:
子类和父类是is-a的关系
2、继承是什么?
类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。
提高代码的复用性!
extends的意思是“扩展”。子类是父类的扩展
不同的叫法:超类、父类、基类、子类、派生类
3、如何使用继承?
使用继承
--编写父类
--编写子类,继承父类
--一个类只能继承一个父类
4、课堂Demo【重点掌握】
子类 Dog.java
package netclass03.extend;
public class Dog extends Pet {
// private String name;
// private int age;
// private String gender;
private String sound;
public Dog(){
// super();
}
// public Dog(String name){
// super(name);
// }
//
// public Dog(int age,String gender){
// super(age,gender);
// }
public Dog(String name, int age, String gender, String sound) {
// super();
// super(name);
// this(age,gender);
super(name,age,gender);
// this.name = name;
// this.age = age;
// this.gender = gender;
this.sound = sound;
}
// public String getName() {
// return name;
// }
//
// public void setName(String name) {
// this.name = name;
// }
//
// public int getAge() {
// return age;
// }
//
// public void setAge(int age) {
// this.age = age;
// }
//
// public String getGender() {
// return gender;
// }
//
// public void setGender(String gender) {
// this.gender = gender;
// }
public String getSound() {
return sound;
}
public void setSound(String sound) {
this.sound = sound;
}
public void show(){
// System.out.println("name:" +this.name +" age:" +this.age +" gender:" +this.gender +" sount:" +this.sound);
System.out.println("name:" +this.getName() +" age:" +this.getAge() +" gender:" +this.getGender() +" sount:" +this.sound);
}
@Override
public void print(){
System.out.println("Dog print... ...");
// super.print();
}
}
子类 Penguin.java
package netclass03.extend;
public class Penguin extends Pet {
// private String name;
// private int age;
// private String gender;
private String color;
public Penguin(){
}
public Penguin(String name, int age, String gender, String color) {
super(name,age,gender);
// this.name = name;
// this.age = age;
// this.gender = gender;
this.color = color;
}
// public String getName() {
// return name;
// }
//
// public void setName(String name) {
// this.name = name;
// }
//
// public int getAge() {
// return age;
// }
//
// public void setAge(int age) {
// this.age = age;
// }
//
// public String getGender() {
// return gender;
// }
//
// public void setGender(String gender) {
// this.gender = gender;
// }
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void show(){
// System.out.println("name:" +this.name +" age:" +this.age +" gender:" +this.gender +" color:" +this.color);
System.out.println("name:" +this.getName() +" age:" +this.getAge() +" gender:" +this.getGender() +" color:" +this.color);
}
}
父类Pet.java
package netclass03.extend;
public class Pet {
private String name;
private int age;
private String gender;
public Pet(){
// super(); //指向顶级父类Object
System.out.println("Pet 空构造器... ...");
}
// public Pet(String name){
// this.name= name;
// }
//
// public Pet(int age,String gender){
// this.age = age;
// this.gender = gender;
// }
public Pet(String name, int age, String gender) {
System.out.println("Pet(String name, int age, String gender)... ...");
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public /*static*/ void print(){
System.out.println("Pet print... ...");
}
private void test(){
System.out.println("Pet test... ...");
}
}
测试类PetTest.java
package netclass03.extend;
/*
* 继承:
* 表示父类跟子类之间的关系
* 当两个类或者多个类具备相同的属性和方法的时候,可以提取出来,变成父类,子类可以继承
*
* 子类跟父类是is-a的关系
*
* 使用:
* 1、使用继承的时候需要使用extends关键字
* 2、使用继承关系之后,父类中的属性和方法都可以在子类中进行使用(非私有属性和非私有方法)
* 3、java中是单继承关系(如果包含多个父类,同时父类中包含重名方法,无法决定该调用谁)
*
*
* super:是 直接父类 对象的引用
* 用途:
* 1、可以在子类中调用父类中被子类覆盖的方法 super.父类方法名称
* 2、当super在普通方法中使用的话,可以任意位置编写
* 3、当super在构造方法中使用的话,会调用父类的构造方法,一定要将super放在第一行
* 4、在构造方法中super关键字和this关键字(指的是不能同时使用this关键字调用重载的构造方法)不能同时出现
* 5、父类中私有的属性和方法都不能被调用,包括构造方法
* 6、子类的构造方法中都会默认使用super关键字调用父类的无参构造方法,因此在定义类的时候,无论自己是否自定义了
* 其他构造方法,最好将无参构造方法写上
* 7、如果构造方法中显式的指定了super的构造方法,那么无参的构造方法就不会被调用
*
* 总结:
* 1、在创建子类对象的时候一定会优先创建父类对象
* 2、所有的java类都具备同一个顶级父类(老祖宗),称之为Object,是所有类的根类
*
* 重写:(覆盖)override
* 必须要存在继承关系,当父类中的方法无法满足子类需求的时候可以选择使用重写的方式
* 注意:
* 1、重写表示的是子类覆盖父类的方法,当覆盖之后,调用同样的方法的时候会优先调用子类
* 2、重写的方法名称,返回值类型,参数列表必须跟父类一致
* 3、子类重写的方法不允许比父类的方法具备更小的访问权限
* 父类 public 子类 public
* 父类 protected 子类 public protected
* 父类 default 子类 public protected default
* 父类的静态方法子类可以进行调用,但是子类不可以重写
* */
public class PetTest {
public static void main(String[] args) {
// Dog dog = new Dog();
// dog.name = "xiaohei";
// dog.setName("小白");
// dog.setAge(10);
// dog.setGender("雄性");
// dog.setSound("汪汪汪~~");
// dog.show();
// dog.print();
Dog dog = new Dog("小白",10,"雄性","汪汪汪~~");
dog.print();
// dog.name = "小黑";
// dog.test();
// Dog dog = new Dog();
// Penguin p = new Penguin("小白",11,"雌性","olive");
// p.show();
}
}
2、java中只有单继承,也就是从子类出发只能有一个直接父类。课堂代码【重点掌握】
父类1--Father1.java
package netclass03.extend;
public class Father1 {
public void test(){
System.out.println("Father1 test... ...");
}
}
父类2--Father2.java
package netclass03.extend;
public class Father2 {
public void test(){
System.out.println("Father2 test... ...");
}
}
子类--SubClassTest.java
package netclass03.extend;
public class SubClassTest extends Father1/*,Father2*/ {
public static void main(String[] args) {
// Father1 father1 = new Father1();
// father1.test();
SubClassTest sct = new SubClassTest();
sct.test();
}
}
3、其他代码--课堂Demo【重点掌握】
PetClassTest.java
package netclass03;
import netclass03.extend.Pet;
public class PetClassTest extends Pet {
public static void main(String[] args) {
PetClassTest pct = new PetClassTest();
pct.print();
}
}
Tiger.java--演示在类中创建set,get方法时,如果出现boolean类型的成员变量,get方法要以is开头。
package netclass03;
public class Tiger {
private String name;
private int age;
private boolean isAnimal;
public Tiger(){
}
public Tiger(String name, int age, boolean isAnimal) {
this.name = name;
this.age = age;
this.isAnimal = isAnimal;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isAnimal() {
return isAnimal;
}
public void setAnimal(boolean animal) {
isAnimal = animal;
}
}
二、继承的理解和super【课堂Demo同上】
1、super是直接父类对象的引用。
2、可以通过super来访问父类中被子类覆盖的方法或属性。
3、普通方法:
没有顺序限制。可以随便调用。
4、构造函数中:
任何类的构造函数中,若是构造函数的第一行代码没有显式的调用super(...);那么
Java默认都会调用super();作为父类的初始化函数。 所以你这里的super();加不加
都无所谓。
5、super实例代码
public class Test {
public static void main(String[] args) {
new ChildClass().f();
}
}
class FatherClass {
public int value;
public void f(){
value = 100;
System.out.println
("FatherClass.value="+value);
}
}
class ChildClass extends FatherClass {
public int value;
public void f() {
super.f();
value = 200;
System.out.println("ChildClass.value="+value);
System.out.println(value);
System.out.println(super.value);
}
}
6、理解继承:
a、子类访问父类成员
使用super关键字代表父类对象
---- 访问父类构造方法
super(); super(name);
在子类构造方法中调用且必须是第一句
---- 访问父类属性
super.name;
---- 访问父类方法
super.print();
b、子类可以继承父类的所有资源吗?
不能被继承的父类成员有哪些?
---- 不能直接访问private成员
---- 子类与父类不在同包,使用默认访问权限的成员
---- 构造方法不能被继承
c、访问修饰符protected
---- 可以修饰属性和方法
---- 本类、同包、子类可以访问
d、访问修饰符总结
e、多重继承关系的初始化顺序是怎样的?
1、父类属性---->2、父类构造方法---->3、子类属性---->4、子类构造方法
f、理解继承示例代码
public class TestExtends {
public static void main(String[] args) {
Mammal m1 = new Mammal();
m1.puru();
m1.eat();
}
}
class Animal {
String eyes="眼睛";
String name="无名";
public void eat(){
System.out.println("动物吃东西!");
}
}
class Mammal extends Animal {
//哺乳
public void puru(){
eyes=“嘴巴”;
System.out.println("小动物吃奶!");
}
}
g、在何处使用继承?
何时使用继承?
---- 继承和真实世界类似
---- 只要说“猫是哺乳动物”,猫的很多属性、行为就不言自明了
---- 藏獒是一种狗
符合is-a关系的设计使用继承
---- 继承是代码重用的一种方式
将子类共有的属性和行为放到父类中
h、代码分析
class Car {
private int site = 4; //座位数
Car(){
System.out.println ("载客量是"+site+"人);
}
public void setSite(int site){
this.site = site;
}
void print(){
System.out.println ("载客量是"+site+"人);
}
}
class Bus extends Car {
Bus(int site){
setSite(site);
}
}
public class BusTest{
public static void main(String[] args) {
Bus bus = new Bus(20);
bus.print();
}
}
i、小结
---- 通过继承可以简化类的定义,实现代码的重用
---- 子类继承父类的成员变量和成员方法,但不继承父类的构造方法
---- java中只有单继承 ,没有像c++那样的多继承。多继承会引起混乱,使得继承链过于复
杂,系统难于维护。就像我们现实中,如果你有多个父母亲,那是一个多么混乱的世界啊。多继
承,就是为了实现代码的复用性,却引入了复杂性,使得系统类之间的关系混乱。
---- java中的多继承,可以通过接口来实现
---- 如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
三、方法重写【课堂Demo同上】
1、在子类中可以根据需要对从基类中继承来的方法进行重写。
2、重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型。
3、重写方法不能使用比被重写方法更严格的访问权限。(由于多态)
4、重写示例代码
public class TestOverride {
public static void main(String[] args) {
Animal animal = new Animal();
animal.shout();
Dog dog = new Dog();
dog.shout();
}
}
class Animal{
void shout(){
System.out.println("发出声音!");
}
}
class Dog extends Animal {
void shout(){
System.out.println("旺旺旺!");
}
}
5、小结:
---- 构造方法也会被重写吗?
不能被继承,因此不能重写
---- 方法重写的规则
方法名相同
参数列表相同
返回值类型相同或者是其子类;
访问权限不能严于父类
---- 方法重载与方法重写的区别
---- super关键字来访问父类的成员
---- super只能出现在子类的方法和构造方法中
---- super调用构造方法时,只能是第一句
---- super和this不能同时出现在构造方法中
---- super不能访问父类的private成员
---- super和this都不能再static方法中
————————————————