一、抽象类:
抽象类的应用场景:
我们在描述一类事物的时候,发现该种事物确实存在着某种行为,但是这种行为目前是不具体的,那么我们可以抽取这种行为的声明,但是不去实现该种行为,这时候这种行为我们称作为抽象的行为,我们就需要使用抽象类。(例如狗会跑,鱼类会游泳)
抽象类的好处: 强制要求子类一定要实现指定的方法。
抽象类要注意的细节:
1.如果一个函数没有方法体,那么该函数必须要使用abstract修饰,把该函数修饰成抽象的函数。。
2.如果一个类出现了抽象的函数,那么该类也必须使用abstract修饰。
3.如果一个非抽象类继承了抽象类,那么必须要把抽象类的所有抽象方法全部实现。
4.抽象类可以存在非抽象方法,也可以存在抽象的方法.
5.抽象类可以不存在抽象方法的。
5.抽象类是不能创建对象的。
疑问:为什么抽象类不能创建对象呢?
因为抽象类是存在抽象方法的,如果能让抽象类创建对象的话,那么使用抽象的对象调用抽象方法是没有任何意义的。
6.抽象类是存在构造函数的,其构造函数是提供给子类创建对象的时候初始化父类的属性的。
abstract不能与以下关键字共同修饰一个方法:
1.abstract不能与private共同修饰一个方法。
2.abstract不能与static共同修饰一个方法。
3.abstract不能与final共同修饰一个方法。
//动物类--->抽象类
abstract class Animal{
Stringname;
String color;
publicAnimal(String name,String color){
this.name= name;
this.color= color;
}
//非抽象的方法
publicvoid eat(){
System.out.println(name+"吃粮食");
}
//移动...
publicabstract void run();
}
//狗是属于动物中一种
class Dog extends Animal{
publicDog(String name,String color){
super(name,color);
}
publicvoid run(){
System.out.println(name+"四条腿跑得很快...");
}
}
//鱼是属于动物中一种
class Fish extends Animal{
publicFish(String name,String color){
super(name,color);
}
publicvoid run(){
System.out.println(name+"摇摇尾巴游啊游!");
}
}
class Demo3 {
publicstatic void main(String[] args)
{
Dogd = new Dog("牧羊犬","棕色");
d.run();
Fishf = new Fish("锦鲤","金黄色");
f.run();
}
}
输出:
牧羊犬四条腿跑得很快...
锦鲤摇摇尾巴游啊游!
二、接口
接口的定义格式:
interface接口名{
}
接口要注意的事项:
1.接口是一个特殊的类。
2.接口的成员变量默认的修饰符为: public static final。那么也就是说接口中的成员变量都是常量。
3.接口中的方法都是抽象的方法,默认的修饰符为: public abstract。
4.接口不能创建对象。
5.接口是没有构造方法的。
6.接口是给类去实现使用的,非抽象类实现一个接口的时候,必须要把接口中所有方法全部实现。
实现接口的格式:
class 类名 implements接口名{
}
接口的作用:
1.程序的解耦。 (低耦合)
2.定义约束规范。
3.拓展功能。
类与接口之间关系:实现关系。
类与接口要注意的事项:
1.非抽象类实现一个接口时,必须要把接口中所有方法全部实现。
2.抽象类实现一个接口时,可以实现也可以不实现接口中的方法。
3.一个类可以实现多个接口。
疑问: java为什么不支持多继承,而支持了多实现呢?
classA{
publicvoid print(){
System.out.println("AAAAAA");
}
}
classB{
publicvoid print(){
System.out.println("BBBBBB");
}
}
classC extends A ,B{
}
newC().print();
接口与接口之间关系:继承关系。
接口与接口之间要注意事项:
1.一个接口是可以继承多个接口的。
,
三、多态
多态:一个对象具备多种形态。(父类的引用类型变量指向了子类的对象),或者是接口的引用类型变量指向了接口实现类的对象)
多态的前提:必须存在继承或者实现关系。
动物 a =new 狗();
多态要注意的细节:
1. 多态情况下,子父类存在同名的成员变量时,访问的是父类的成员变量。
2. 多态情况下,子父类存在同名的非静态的成员函数时,访问的是子类的成员函数。
3. 多态情况下,子父类存在同名的静态的成员函数时,访问的是父类的成员函数。
4. 多态情况下,不能访问子类特有的成员。(如果需要访问子类特有的成员,那么需要进行类型强制转换。类型转换最场景的问题: java.lang.ClassCastException。 强制类型转换失败。)
总结:多态情况下,子父类存在同名的成员时,访问的都是父类的成员,除了在同名非静态函数时才是访问子类的。
编译看左边,运行不一定看右边。
编译看左边:java编译器在编译的时候,会检查引用类型变量所属的类是否具备指定的成员,如果不具备马上编译报错。
//动物类
abstract class Animal{
Stringname;
String color = "动物色";
publicAnimal(String name){
this.name= name;
}
publicabstract void run();
publicstatic void eat(){
System.out.println("动物在吃..");
}
}
//老鼠
class Mouse extends Animal{
Stringcolor = "黑色";
publicMouse(String name){
super(name);
}
public void run(){
System.out.println(name+"四条腿慢慢的走!");
}
publicstatic void eat(){
System.out.println("老鼠在偷吃..");
}
//老鼠特有方法---打洞
publicvoid dig(){
System.out.println("老鼠在打洞..");
}
}
class Fish extends Animal {
publicFish(String name){
super(name);
}
public void run(){
System.out.println(name+"摇摇尾巴游..");
}
}
class Demo11
{
publicstatic void main(String[] args) {
//多态:父类的引用类型变量指向子类的对象
Animala = new Mouse("老鼠");
a.dig();
}
}
输出结果:老鼠在打洞..
四、多态的应用:
1. 多态用于形参类型的时候,可以接收更多类型的数据。
2. 多态用于返回值类型的时候,可以返回更多类型的数据。
多态的好处:提高了代码的拓展性。
需求1:定义一个函数可以接收任意类型的图形对象,并且打印图形面积与周长。
//图形类
abstract class MyShape{
publicabstract void getArea();
publicabstract void getLength();
}
class Circle extends MyShape{
publicstatic final double PI = 3.14;
doubler;
publicCircle(double r){
this.r=r ;
}
public void getArea(){
System.out.println("圆形的面积:"+PI*r*r);
}
public void getLength(){
System.out.println("圆形的周长:"+2*PI*r);
}
}
class Rect extends MyShape{
intwidth;
intheight;
publicRect(int width , int height){
this.width= width;
this.height= height;
}
public void getArea(){
System.out.println("矩形的面积:"+width*height);
}
public void getLength(){
System.out.println("矩形的周长:"+2*(width+height));
}
}
class Demo12 {
public staticvoid main(String[] args) {
Circlec = new Circle(4.0);
print(c);
Rectr = new Rect(3,4);
print(r);
}
//定义一个函数可以接收任意类型的图形对象,并且打印图形面积与周长。
publicstatic void print(MyShape s){ // MyShpe s = new Circle(4.0);
s.getArea();
s.getLength();
}
}