标签:ima 简单 限制 int return 转化 情况 叠加 基于
本人为自学Java系列,内容来自于中国大学mooc华东师范大学陈育良教授《Java核心技术》,在此感谢老师!
一:继承
面向对象和面向过程编程语言最大的特点就是变量类型的继承,通过extend去继承父类
继承能够解决很多类型的重复定义,类别内的对象属性和方法都具有一定的共同点。将共同点提取出来,即形成父类/基类/超类—Parent class/Base class/Super class
其他类型则自动生成子类/派生类-----Child class/Derived class
Human类把Man和Woman的height、weight成员属性和eat方法写成一个父类,两个子类就能继承Human,从而节约很多重复定义。
?
子类会继承父类所有的属性和方法,但是不能访问private成员。
子类会继承父类的父类所有的属性和方法,但是不能访问private成员
单根继承原则:每个类都只能继承一个类,如果不写extends,Java类都默认继承java.lang.object,Objecvt里面默认有clone equlas finalize getcalss hashCode toString等方法
同样方法名和参数情况下,本类的方法会比父类的方法优先级更高
父类:
public?class?Base?{??
?private?int?num?=?10;??
??public?int?getNum()?{??
??????return?this.num;??
??}??
}??
子类:
public?class?Derived?extends?Base{??
????private?int?num?=?20;?????
??????
?
????public?int?getNum()?{??
????????return?this.num;??
????}?????
??????
?
????public?static?void?main(String[]?args)?{??
????????Derived?foo?=?new?Derived();??
????????System.out.println(foo.getNum());??
????}??
}??
程序返回值为20。子程序会选择本类的方法进行执行。
?
解释下上章节的继承函数
public?class?A?{??
?public?A()?{??
?????System.out.println("11111");??
?}??
?public?A(int?a)?{??
?????System.out.println("22222");??
?}??
}??
?
public?class?B?extends?A?{??
?public?B()?{??
?????//super();??
?????System.out.println("333333");??
?}??
?public?B(int?b)?{??
?????//super(b);??
?????System.out.println("444444");??
?}??
????public?static?void?main(String[]?args)?{??
????????//?TODO?Auto-generated?method?stub??
?????????B?obj?=?new?B();??
?????????System.out.println("==========");??
?????????B?obj1?=?new?B(10);??
????}??
??
?
}??
输出结果:
11111??
333333??
==========??
11111??
444444??
两个构造器都会默认调用父类的无参构造函数,输入11111.
当我们在每个构造器前面加上super函数,而且super语句必须放在第一条。
当去掉第二行super(b)注释,输出值:
11111??
333333??
==========??
22222??
444444??
二:抽象类
抽象类:属性+方法组成,完整的类所有的方法都有实现(方法体),一个完整的类才可以被实例化,如果一个类暂时没有方法实现,就定义为抽象类,抽象类是无法被实例化的。
--optional 成员变量,个数不限
--optional具体方法,方式有实现,个数不限
-- optional 抽象方法,加abstract关键字,个数不限
同时对于抽象类我们还要遵循以下的规则
抽象类:
public?abstract?class?Shape?{??
????int?area;??
????public?abstract?void?calArea();??
??
?
}??
完整类继承于抽象类,并实现抽象类中的方法体。
public?class?Rectangle?extends?Shape?{??
??int?width;??
??int?length;??
??public?void?set(int?length,?int?width)?{??
??????this.width?=?width;??
??????this.length?=?length;??
??}??
??public?void?calArea()?{??
??????System.out.println(this.length?*this.width);??
??}??
????public?static?void?main(String[]?args)?{??
????????//?TODO?Auto-generated?method?stub??
?????????Rectangle?obj?=?new?Rectangle();??
?????????obj.set(10,5);??
?????????obj.calArea();??
????}??
??
?
}??
三:接口
紧接继承的定义,如果类的所有方法都没有实现,那么这个类就是接口interface。类只可以继承-extends一个类,但是可以实现-implements多个接口,继承和实现可以同时进行
类可以继承多个接口,没有实现的方法将会叠加,即A继承与B C两个接口,B C两个接口所有方法体将会叠加,如果类没有实现接口所有方法,只能定义为抽象类
接口里可以定义变量,但是一般是常量,详情可以参考final节
这里给大家写几个简单的例子来描述: 类-抽象类-接口之间的关系
?
定义三个接口:
public?interface?Aninmal?{??
????public?void?eat();??
????public?void?move();??
}??
接口2:
public?interface?ClassTree?{??
??public?void?climb();??
}??
接口3
public?interface?CatFamliy?extends?ClassTree,?Aninmal?{??
//?继承多个接口相当于将没有实现的方法全部叠加??
????//?eat()??
????//?move()??
????//climb()??
}??
Cat类是实现与Animanl接口的,必须实现它所有的方法体
public?class?Cat?implements?Aninmal?{??
????public?void?eat()?{??
????????System.out.println("Cat?can?eat");??
????}??
????public?void?move()?{??
????????System.out.println("Cat?can?move");??
????}??
}??
类LandAnimal由于只实现Animal中的move方法,没有实现eat方法,定义为abstract类
public?abstract?class?LandAnimal?implements?Aninmal?{??
????public?void?move()?{??
????????System.out.println("LandAnimal?cat?move");??
??????????
?
????}??
????//public?abstract?void?eat();??
}??
Rabbit类是先继承LandAnimal抽象类再实现ClassTree接口
public?class?Rabbit?extends?LandAnimal?implements?ClassTree?{??
//?必须先继承再实现??
????public?void?eat()?{??
????????System.out.println("Rabbit?cat?eat");??
????}??
????public?void?climb?()?{??
????????System.out.println("Rabbit?can?climb");??
????}??
}??
Tiger类是实现CatFamily接口,所以要实现这个接口所有方法
public?class?Tiger?implements?CatFamliy?{??
????public?void?move()?{??
????????System.out.println("Tiger?can?move");??
????}??
????public?void?eat()?{??
????????System.out.println("Tiger?can?move");??
????}??
????public?void?climb()?{??
????????System.out.println("Tiger?can?move");??
????}??
}??
四:转型
基本类型转型
变量支持相互转化。比如 int?a?=?(int)3.5?这里进行变量的强转换
基本类型转换:
从高精度往低精度转化,会损失信息,称为收缩变换。这种情况我们需要声明类型转化
从低精度往高精度转化,不损失信息,称为宽松变换。这种情况Java会自动转化。
public?class?Test{??
????public?static?void?main(String[]?args)?{??
????????int??a;??
????????a?=?(int)3.5;??// 收缩变换
????????System.out.println(a);??
????????double?b?=?3;??// 宽松变换
????????System.out.println(b);??
?????????}??
结果:
3??
3.0??
类转型
类型之间可以互相转型,但是只限制于有继承关系的类
---子类可以转化为父类,但是父类不能转化为子类。因为子类有更多的方法和变量
---子类继承父类所有的财产,子类转化为父类(从大到小,即向上转型);从父类直接变成子类(从小变大,即向下转型)
public?class?Man?extends?Human?{??
????public?void?eat()?{??
????????System.out.println("i?cat?eat?more");??
????}??
????public?void?plough()?{??
??????????
?
????}??
??public?static?void?main(String[]?arsg)?{??
??????Man?obj1?=?new?Man();??
??????obj1.eat();??
??????Human?obj2?=??new?Man();//?upcast向上转换??
??????obj2.eat();??
????????Man?obj3?=?(Man)obj2;??
????????obj3.eat();??
//????Man?obj3?=?new?Human();??Human是父类,Man拥有父类不具有的成员变量与方法。??
//?????所以Human对象内存无法转型为Man类??
??}??
}??
父类:
package service;
?
public
class Human {
int
height;
int
weight;
public
void eat() {
???? System.out.println("I cat eat");
}
}
输出结果:
i cat eat more
i cat eat more
i cat eat more
?
如上序程序就有类转型,Man类转为Human类,即衍生类引用转为基类引用。类型转换的作用就是带来多态。
程序中有一个eat方法,和父类中的eat方法方法名和参数一致,我们把这个称为方法重写。(不同于重载,重载是方法名一致但是形参类型或者个数不一致)。且子类方法的优先级高于父类。
五:多态
多态拥有三个必要条件:
继承 extends
重写 overwrite
父类引用指向子类对象 Father obj = new Son()
当我们使用多态调用方法时,对象会检查父类是否有此方法,如果没有就会编译错误。如果有的话,就会调用子类同名方法。
?
多态的作用到底有什么呢:
以统一的接口来操纵某一类中不同对象的动态行为
对象之间的解耦
代码实例:
public
interface
Aninmal {
public
void eat();
public
void move();
}
?
?
public
class Dog implements Aninmal {
????public
void eat() {
????????System.out.println("Dog can eat");
????}
public
void move() {
????????System.out.println("Dog can move");
????}
}
?
?
public
class Cat implements Aninmal {
????public
void eat() {
????????System.out.println("Cat can eat");
????}
public
void move() {
????????System.out.println("Cat can move");
????}
}
public?class?AnimalTest?{??
??public?static??void??haveLunch(Aninmal?a)?{??
??????a.eat();??
??}??
??Aninmal?a;??
??AnimalTest?c?=?new?AnimalTest();??
??public?static?void?main(String[]?args)?{??
?????haveLunch(new?Cat());?//?此处等于转型??Aninaml?a?=?new?Cat();?haveLunch(a)??
?????haveLunch(new?Dog());??
?????haveLunch(new?Aninmal()?{??
??????????
?
????????@Override??
????????public?void?move()?{??
????????????//?TODO?Auto-generated?method?stub??
????????????System.out.println("move?Test");??
????????}??
??????????
?
????????@Override??
????????public?void?eat()?{??
????????????//?TODO?Auto-generated?method?stub??
????????????System.out.println("?eat?Test");??
????????}??
????});??
??}??
}??
输出结果:
Cat?can?eat??
Dog?can?eat??
?eat?Test??
?
我们通过Animal接口,完成对于Dog和class两个不同对象的自己各自独有的行为。第三个是匿名类,重写补全Animal接口的方法,调用补全的方法。
我们haveLunch方法形参可以传入不同对象,这个称为对象的解耦。
?
六:契约设计
契约:通过接口定义了方法的名称,参数和返回值。规范了派生类的行为
基于接口,利用转型和多态,不影响真正方法调用,成功地将调用类和被调用类解耦。
两个方法之间已经解耦设计,havelunch已经定义其方法名 参数名和方法体,调用类可以利用多态的功能实现多个对象的不同行为方法。
{Java初级系列四}---继承、接口和抽象类
标签:ima 简单 限制 int return 转化 情况 叠加 基于
原文地址:https://www.cnblogs.com/yblecs/p/12272740.html