JAVA学习笔记之继承,多态和接口
<1>继承
1如何表达这个关系呢?
通过extends关键字可以实现类与类的继承
格式:
class子类名 extends 父类名 {
}
父类:基类,超类
子类:派生类
继承的特点:
A:Java只支持单继承,不支持多继承。
B:Java支持多层(重)继承(继承体系)。
2什么时候使用继承呢?
我们可以从多个事物中根据属性将其用相同的食物概括的时候,及两者属于“is a”的关系时
3继承间的成员变量关系:
A:名字不同,非常简单。
B:名字相同
首先在子类局部范围找
然后在子类成员范围找
最后在父类成员范围找(肯定不能访问到父类局部范围)
如果还是没有就报错。(不考虑父亲的父亲…)
就近原则。
4继承间构造方法的关系:
子类中所有的构造方法默认都会访问父类中空参数的构造方法(super()),且这句话必须在子类构造方法的第一条语句,当你自己写出时;如果是没写,则默认。
原因:因为子类会继承父类中的数据,可能还会使用父类的数据。
所以,子类初始化之前,一定要先完成父类数据的初始化。
每个子类的构造方法的第一行,有一条默认的语句:
super();
注意:仅仅是完成数据的初始化,创建对象目前必须用new申请空间。
下面给出继承示例的相关代码:
packagecom.edu_04;
publicclass Animal {
//成员变量
private Stringtype;
private Stringname;
privateintage;
//set,get方法
public String getType() {
returntype;
}
publicvoid setType(Stringtype) {
this.type = type;
}
public String getName() {
returnname;
}
publicvoid setName(Stringname) {
this.name = name;
}
publicint getAge() {
returnage;
}
publicvoid setAge(intage) {
this.age = age;
}
//有参无参构造
public Animal(){System.out.println("这是Animal的无参构造");}
public Animal(Stringtype,Stringname,intage){
System.out.println("这是Aniaml的有参构造");
this.type = type;
this.name = name;
this.age = age;
}
publicvoid eat(){
System.out.println("动物喜欢吃粮食");
}
}
packagecom.edu_04;
publicclass Dogextends Animal{
// 建立Dog的有参无参构造
public Dog(){System.out.println("这是Dog的无参构造方法");}
public Dog(Stringtype,Stringname,intage){
super(type,name,age);
System.out.println("这是Dog的有参构造方法");
setAge(age);
setName(name);
setType(type);
}
}
publicclass Test {
publicstaticvoid main(String[]args) {
Dog d=new Dog();
d.setAge(10);
d.setName("lixiaojuan");
d.setType("金毛");
System.out.println(d.getName()+" "+d.getType()+" "+d.getAge());
System.out.println("---------------------------");
Dog d2 =new Dog("藏獒","lixiaojuan",10);
d2.eat();
}
}
<2>多态
·基本概念:同意对象在不同时刻的不同表现形式;如水的不同形态,液态水,水蒸气,冰,但这里有些许不同,不同形态的对象,代码所实现的功能不同。
·多态的前提:
A:有继承关系
B:有方法重写(不是必要条件,但是只有有了方法重写多态才有意义)
C:有父类引用 指向 子类对象
Fu f= new Fu();
左边:Fu类型的引用
右边:Fu类型的对象
Zi z = new Zi();
Fu f = new Zi();
·成员访问特点
A:成员变量
编译看左边,运行看左边
B:构造方法
子类构造默认访问父类的无参构造
C:成员方法(重点理解)
编译看左边,运行看右边
为什么变量和方法不一样呢?
方法重写。
D:静态成员方法
编译看左边,运行看左边
因为静态的内容是和类相关的,与对象无关。
·抽象类
··抽象类特点:
A:抽象类和抽象方法必须用abstract关键字修饰
B:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
C:抽象类不能实例化
那么,如果实例化并使用呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
D:抽象类的子类
要么是抽象类
要么重写抽象类中的所有抽象方法
··抽象类的作用:
强制要求子类必须要重写某些方法。
··抽象类的成员:
成员变量:可以是变量,也可以是常量。
构造方法:有构造方法
不能实例化,构造方法有什么用呢?
用于子类访问父类数据的初始化。
成员方法:既可以是抽象的,也可以是非抽象的。
抽象类及多态的示例代码:
class Fu{
intage;
intnum = 30;
public Fu(){
System.out.println("这是fu的无参构造器");
}
public Fu(intage){
System.out.println("这是Fu的有参构造");
this.age = age;
}
publicvoid show(){
System.out.println("fu的show方法");
}
publicvoid method(){
System.out.println("fu的method方法");
}
}
class Zi extends Fu{
intage;
intnum = 20;
public Zi(){
System.out.println("这是Zi的无参构造器");
}
publicvoid show(){
System.out.println("Zi的show方法");
}
publicvoid method(){
System.out.println("zi的method方法");
}
}
publicclass DuoTaiDemo {
publicstaticvoid main(String[]args) {
Fu f =new Zi();//父类引用指向子类对象
System.out.println(f.num);
System.out.println("-------------");
f.show();
System.out.println("-------------");
f.method();
}
}
publicabstractclass Animal {
private Stringtype;
private Stringname;
public Animal(){}
public Animal(Stringtype,Stringname){
this.setType(type);
this.setName(name);
}
public String getType() {
returntype;
}
publicvoid setType(Stringtype) {
this.type = type;
}
public String getName() {
returnname;
}
publicvoid setName(Stringname) {
this.name = name;
}
publicabstractvoid eat();
}
publicclass Catextends Animal{
public Cat(){}
public Cat(Stringtype,Stringname){
setType(type);
setName(name);
}
publicvoid eat(){
System.out.println("猫爱吃鱼");
}
publicvoid catchMouse(){
System.out.println("猫会捉老鼠");
}
}
publicclass Test {
publicstaticvoidmain(String[] args) {
Animal a =new Dog();
a.eat();
Dog d = (Dog)a;
d.lookDoor();
System.out.println("-------------------");
Animal a2 =new Cat("xiaojaun","加菲猫");
a2.eat();
Cat c = (Cat)a2;
c.catchMouse();
System.out.println(c.getName() + " " +c.getType());
//子类c继承了父类a2的成员
}
}
<3>接口
·当我们可以从多个对象中可以提取出相同的特点时,我们便可以用接口表示这一特点
·基本概念:类实现接口代表着这个类自身功能的一种扩展
·接口的特点:
A:定义接口要用关键字interface表示
格式:interface接口名 {}
B:类实现接口用implements表示
格式:class类名 implements接口名 {}
C:接口不能实例化
那么,接口如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。
D:接口的实现类
要么是抽象类
要么重写接口中的所有抽象方法
·接口的成员特点:
A:成员变量
只能是常量。
默认修饰符:public static final
B:构造方法
没有构造方法
C:成员方法
只能是抽象方法。
默认修饰符:public abstract
·类与类:
继承关系。只能单继承,可以多层(重)继承。
·类与接口:
实现关系。可以单实现,也可以多实现。
还可以在继承一个类的同时实现多个接口。
·接口与接口:
继承关系。可以单继承,也可以多继承。
相关理解性代码如下:
publicclass Person {
private Stringname;
private Stringgender;
//建立有参无参构造
public Person(){}
public Person(Stringname,Stringgender){
this.setName(name);
this.setGender(gender);
}
//建立相应的get()set()方法
public String getName() {
returnname;
}
publicvoid setName(Stringname) {
this.name = name;
}
public String getGender() {
returngender;
}
publicvoid setGender(Stringgender) {
this.gender = gender;
}
publicvoid love(){
System.out.println("人知道爱");
}
}
publicclass Studentextends Person{
public Student(){}
public Student(Stringname,Stringgender){
setName(name);
setGender(name);
}
publicvoid task(){
System.out.println("学生会写作业");
}
publicvoid show(){
System.out.println(this.getName() + " " +this.getGender());
}
}
publicinterface SmokingInter {
publicabstractvoid somke();
}
publicclass SomkingStudentextends Studentimplements SmokingInter{
public SomkingStudent(){}
@Override
publicvoid somke() {
//TODO Auto-generated method stub
System.out.println("这个学生会抽烟");
}
}
publicclass Test {
publicstaticvoid main(String[]args) {
Person p =new Student();
p.love();
Student s = (Student)p;
s.task();
System.out.println("--------------------");
SomkingStudent ss =newSomkingStudent();
ss.love();
ss.task();
ss.somke();
}
}
publicclass Teacherextends Person{
public Teacher(){}
public Teacher(Stringname,Stringgender){
setName(name);
setGender(gender);
}
publicvoid Speak(){
System.out.println("这个老师能讲课");
}
}
publicclass SmokingTeacherextends Teacherimplements SmokingInter{
@Override
publicvoid somke() {
//TODO Auto-generated method stub
System.out.println("这老师抽烟");
}
}