(面向对象3)继承,类的关联和依赖,多态,final关键字,抽象类,接口

面向对象特征—继承

继承:

继承是面向对象程序设计不可缺少的设计思想,是实现代码可重用的根基,是提高代码可扩展性的主要途径。

继承是从已有的类中派生出新的类,新的类能吸收已有类的属性和行为,并能扩展新的能力。

  • 在JAVA中使用extends关键字来表示继承关系。
  • JAVA不支持多继承,单继承使JAVA的继承关系很简单,一个类只能有一个直接父类。
  • 继承之后子类可以调用父类的所有非私有属性和非私有方法

何时使用继承?

  • 符合is-a关系的设计,使用继承
  • 将子类共有的属性和行为放到父类中
    继承的形式:
    [访问权限修饰符][修饰符] 子类名 extends 父类名{子类体}
public class Animal{
	public void eat(){}
}

public class Dog  extends Animal{
	public void play(){} 
}

//子类对象可以直接调用父类的方法,强调复用性
 Dog  dog = new Dog ();
     dog.eat();

继承的传递性:

C类从B类继承,B类又从A类继承
那么C类就具有B类和A类的所有非私有属性和非私有方法

当一个没有继承任何一个类时,jvm会默认让类继承Object类
Object是 java为所有类提供的基类

继承中的构造方法:

  • 子类构造方法总是先调用父类构造方法,默认情况下,调用父类无参构造方法
  • 可以在子类构造方法的第一行,使用super关键字调用父类任意一个构造方法
  • 如果用super,必须写在构造方法的第一句
  • 如果子类的构造方法中没有显式地调用基类构造方法,则系统默认调用基类无参数的构造方法。

原因:子类创建后需要调用父类的方法,所以在创建子类对象是父类也需要同时被创建.

super关键字用途

super关键字代表父类的引用,在程序中主要的用途
在子类构造方法中要调用父类的构造方法,需要注意:super语句只能出现在子类构造方法体的第一行。

  • 用“super.成员变量名”来引用父类成员变量
  • 用“super.方法名(参数列表)”的方式访问父类的方法。
  • 与this的区别,this通常指代当前对象,super通常指代父类。

方法的重写(OverRide) overload重载:

在子类中可以根据需要对从基类中继承来的方法进行重写。
方法重写规则

  • 方法名相同、参数列表相同;
  • 返回值类型相同;
  • 访问权限相同

即与父类方法结构完全相同
注意:构造方法不能重写

应用场景:

当父类的方法实现不能满足子类需求时,可以对方法进行重写( override)

类之间关系—关联,依赖

关联关系:

对象和对象之间的连接。在Java中,关联关系的代码表现形式为一个类做为另一个类的属性类型存在。
即“有”的关系:”has-a”。

关联关系分为单向关联和双向关联:

单向关联: A类关联B类。
双向关联:A类关联B类,B类关联A类;

 public class Phone {
        private  Person   per;//关联Person类
     }
public  class Person {
		private Phone phone;//关联Phone类
}

关联关系的多重性

  • 一对一关联

  • 一对多关联
    解决一对多的关联的方案

  • 集合

public class Classes{     
     }
    public  class Student{
    private List Classess;
    }
  • 数组
 public class Classes{     
    
    }
    public  class Student{
    private Classes[] Classess;
    
    }

依赖关系(use-a):

指一个类A使用到了另一个类B

依赖关系的特性:

这种关系是具有偶然性的、临时性的、非常弱的,但是类B的变化会影响到类A。

依赖具体表现:

在代码层面,依赖关系表现为类B作为参数被类A在某个method
方法中使用
例:

public  class Person {
       public void travel(Bus bus){
       }
}

依赖与关联

关联是“HAS”关系,依赖是“USE”关系
A类关联B类,指的是B类对象作为A类的属性存在,称为“has”关系。
A类依赖B类,指的是B的对象作为A类的方法参数存在,称为“use”关系。

面向对象特征—多态

多态:

同一种事物,在不同时刻表现不同的状态

多态存在的三个必要条件:

  • 要有继承(包括接口的实现)(前提条件)
  • 要有重写(前提条件)
  • 父类引用指向子类对象

当编译期类型是父类,运行期类型是子类时,被称为父类引用指向子类对象

class  Animal{
               …… 
}
class Cat  extends Animal{
               ……
}
class Dog extends Animal {
               ……
}
Animal x = new Cat()  //Animal 的引用指向Cat的对象

多态环境下对成员方法的调用

class  Animal{
           void show() {
             System.out.println(“Anmial");
          }
}
class Cat  extends Animal{
              void show() {
                    System.out.println(“cat");
              }
}
…….
Animal x = new Cat() 
   x.show() //调用的方法和父类同名时,默认调用子类中的方法,子类中没有此方法时再调用父类的方法

简单的说:编译看左边,运行看右边。

多态环境下对静态成员方法的调用

class  Animal{
          static  void show() {
             System.out.println(“Animal");
          }
}
class Cat extends Animal {
             static  void show() {
                    System.out.println(“Cat");
              }
}
…….
Animal x = new Cat() 
   x.show() //调用的是动物类中的静态成员方法。

简单的说:编译和运行都看左边。

多态环境下对成员变量的调用

class Animal{
       int num = 3;
}
class Cat  extends Animal {
       int  num = 4;
}
Animal x = new Cat() 
x.num; //调用的是动物类中的成员变量。

简单的说:编译和运行都看等号左边。
注意:变量不存在被子类覆写这一说法,只有方法存在覆写。

方法参数具有多态性

class  Animal{
           void eat() {}
}
class  Cat extends Animal{
            void eat() {}
}
class Dog extends Animal{
            void eat(){}
}
//方法的形式参数类型是父类类型,而传递的实际参数可以是任意子类的对象
method(Animal  animal){  
     animal .eat();                
}

方法参数多态性的好处:提高代码的扩展性

向上转型

class Animal{
   void eat(){ }
}
class Cat extends Animal{
      void look() {
	System.out.println("看家");
	 }
    }      
 ………
   Animal x=new Cat()  //向上造型,Cat对象提升到Animal对象
   x.eat()   //只能使用父类中的方法
   x.look()  //报错!不能使用子类中的方法

向上转型的作用是:提高程序的扩展性。

向下转型

class Animal{
      void eat(){ }
}
class Cat extendsAnimal{
      void look() {
          System.out.println("看家");
      }
    }      
 ………
Animal x=new Cat()
Cat  m=(Cat)x;  //向下转型
   m.eat() ;
   m.look();//子父类中的方法都可以使用

向下转型的作用是:为了使用子类中的特有方法。

final关键字

  • final 用于声明属性,方法和类
  • 属性:定义就必须直接赋值或者在构造方法中进行赋值,并且后期都不能修改。
  • 方法:子类里不可被覆盖(重写)。
  • 类:不能被定义为抽象类或是接口,不可被继承。

final属性赋值:

在声明时同时赋值,往往与static一起使用
声明时不赋值,必须在构造方法中逐一赋值

总的原则:保证创建每一个对象的时候,final属性的值是确定的

private int index;
private static final double pai=3.14;
private final  int  level;

public Test(){
      level=0;
}

public Test(int index){
    this.index=index;
    level=1;
}

对参数做final修饰
在方法参数前面加final关键字,为了防止数据在方法体中被修改。

public class Demo12 {
    private int a=1;
    public void ww(final int a){
        a=12;
    }
}

抽象类

  • 用abstract修饰的类就是抽象类。如果某个类中包含有抽象方法,那么该类就必须定义成抽象类。

  • 抽象方法

    • 抽象方法是一种特殊的方法:它只有声明,而没有具体的实现
    • 抽象方法必须用abstract关键字进行修饰
  • 抽象类可以有成员属性和非抽象的成员方法。

  • 抽象类不能被实例化,但可以有构造函数,因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。

  • 抽象类只能用作基类,表示的是一种继承关系。继承抽象类的非抽象类必须实现其中的所有抽象方法,而已实现方法的参数、返回值要和抽象类中的方法一样。否则,该类也必须声明为抽象类。

  • 构造方法和静态方法不可以修饰为abstract

抽象类,抽象方法,在软件开发过程中都是设计层面的概念。也就是说,设计人员会设计出抽象类,抽象方法,程序员都是来继承这些抽象类并覆盖抽象方法,实现具体功能。

接口

认识一下接口

public interface MyInterface {
       int num = 10; //所有属性默认为: public static final

 public  void  foo();//所有方法都是:public abstract
    //其他方法
}

必须知道的接口特性

  • 接口不可以被实例化
  • 实现类必须重写接口的所有方法
  • 实现类可以实现多个接口
  • 接口中的变量都是静态常量
    面向接口编程
    接口存在的意义:java中一个类只能有一个父类,所以用接口可以实现多继承的逻辑 。

从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。

接口的定义和使用

接口的定义:使用 interface 关键字用来声明一个接口。

public interface Animal {
    String type="爬行";
    int count=34;
    void eat();
    void sleep();
    default void test1(){
        System.out.println("测试一");
    }
    public static void test2(){//接口中的静态方法只能用类名调用
        System.out.println("测试二");
    }
}
public interface PersonFriend {
}

[访问修饰符] interface 接口名称 [extends 其他的接口名1,….其他的接口名n] {
// 声明常量
// 抽象方法
}

接口的使用:类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
[访问修饰符] class 类名 implements 接口名1,接口名2……{ }

class Dog implements Animal ,PersonFriend{
    @Override
    public void eat() {
        System.out.println("吃");
    }
    @Override
    public void sleep() {
        System.out.println("睡觉");
    }
}

结合继承:
[访问修饰符] class 类名 extends 父类名 implements 接口名1,接口名2……{ }

接口的特性

  • 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  • 接口中每一个方法也是隐式抽象的,默认为public abstract 。
  • 接口中声明的属性默认为 public static final 的;
  • 接口不是被类继承了,而是要被类实现。
  • 接口不能实例化对象(无构造方法),但可以声明对象的引用。(多态性)
  • 多个类可以实现同一个接口。
  • 一个类可以实现多个接口,但只能继承一个类。
  • 与继承关系类似,接口与实现类之间存在多态性。
  • 一个接口能继承其它多个接口。
  • 当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类

接口和抽象类的区别

语法上的区别:

  1. 抽象类里可以有构造方法,而接口内不能有构造方法。
  2. 抽象类中可以有普通成员变量,而接口中不能有普通成员变量。
  3. 抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的。
  4. 抽象类中的抽象方法的访问类型可以是public
    ,protected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
  5. 抽象类中可以包含静态方法,接口内不能包含静态方法。
  6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义 静态常量。

相同点:
抽象类和接口都不能用来创建对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值