首页 > 代码库 > JAVA-面向对象

JAVA-面向对象


软件公司做项目的流程:

 1 可行性分析

 2 需求分析,客户要什么?需要和客户多次沟通,通过需求分析文档的确认来确定。

 3 商业建模,大型项目需要。

 4 项目分析和设计。有些公司设计分概要设计和详细设计。

 5 编码(程序员的主业)

 6 测试(测试工程师)

 7 部署

 8 维护


面向对象(OO)的编程

   面向对象的编程思想的核心就是 一切皆是对象。

    面向对象和面向过程是目前常见的编程思想,面向过程就是编程时以数据的流程(过程)作为核心的编程。C语言是面对过程的代表,其它的主流都是面向对象的编程语言。

    面向对象以现实为编程思想,现实是什么样子,代码就怎么实现。

   OOA - 面向对象的分析

   OOD - 面向对象的设计

   OOP - 面向对象的编程

   OOT - 面向对象的测试



  面向对象的核心概念

   类/对象/属性(成员变量)/方法(成员方法)/构造方法

   重载(当一个类中写上两个或多个构造,自然形成构造方法的重载。重载就是类名同名但参数列表不同)

   重写(当子类从父类中继承下来的方法不足以满足子类的要求,就需要对父类中的方法进行重写/覆盖,以满足子类需求)

   封装/继承/多态


   Java的一些关键字:

     this和super、static、final、abstract等


   面向对象的三大基本特性: 封装、继承、多态。

    四大对象的基本特征:封装、继承、多态、抽象。


  Java编程以类class作为基本单位,写代码先写class。


  是客观世界中同一类事物的统称,是对同一类事物的抽象,是概念,客观世界中其实是不存在类的。

  对象就是客观世界中的每一个具体事物。

  引用就是对象的标号,客观世界中一般就是名字,代码中就是变量名。


  写程序要写类,调用代码时用对象。


  Scanner sc = new Scanner(System.in);     //创建对象

   Scanner是类, sc是引用, new Scanner() 是对象。


  属性/方法和构造方法

   同一类事物的特征/状态 叫属性(Field)/字段,也叫成员变量。

   同一类事物的行为/功能 叫方法,也叫成员方法。

   构造方法就是创建对象时调用的,用于创建某类事物的对象。


  一个类的代码由 属性/方法和构造方法 组成,但属性和方法可有可无


  类的语法:

    修饰符  class  类名{

      //属性/方法和构造

    }

    修饰符可以不写


  属性(成员变量)的语法:(属性是直接定义在类体中的变量)

    修饰符  变量类型(基本型和引用型)  变量名 = 初始值;

    修饰符可以不写, = 初始值也可以不写。

    如果属性不给初始值,有默认值(变量不一定)。默认值和数组元素的一样。

    整型都是0,浮点都是0.0,布尔都是false,字符型默认为空格,引用类型都是null。

    默认值没有实际的意义。


  方法(成员方法)的语法

    修饰符  返回值类型  方法名(参数列表) throws Exception(抛异常) { }

    修饰符可以不写,返回值类型如果没有返回值,写void。

    throws Exception 可以不写。参数列表如果没有参数,写() 。


  属性和方法的区分:有()的是方法,没有()是属性。


  练习:

   写一个类Point(点),里面有两个int类型的属性x和y。(能javac不能java)

publilc class Point{

  int x;

  int y;

}



  创建对象的方法:

    new 构造方法(参数列表);     (new加构造方法(修饰符 类名(参数列表))组成对象)

    参数列表可以没有,但是()必须有。

    new 后面只能跟构造方法,对象/引用后面可以用.调用属性和方法。


  内存的区域划分:

    内存分为:代码区(方法区)、字符串常量区、栈区/堆栈区stack、堆区heap等。


     代码区存放代码,主要是方法和构造方法。


     字符串常量区主要放各种字符串常量,就是""格式的字符串。


     栈区存放各种局部变量,包括方法的参数。特点的是后进先出。


     堆区是一大片内存,new的东西全部在堆区。


   C/C++程序员用指针操作内存,Java程序没有指针,Java程序员不需要管内存的事情。

   JVM处理内存。 new 可以分配堆内存(创建对象就是在堆中开辟内存空间),内存回收由JVM启动gc回收垃圾。



   Point p = new Point();不是一个语句,由3个语句组成:

   1 Point p 会在栈内存中放一个变量p进去。

   2 new Point() 会在堆内存中创建一个新的Point对象,里面有x和y,值为0。

   3 = 就是赋值,把对象的首地址赋值给p。


  练习:

   写一个TestPoint类,写主方法,然后创建一下Point对象,再把坐标设置1,2。

然后打印一下点的坐标。



  方法有三要素: 返回值类型、方法名、参数列表。


    方法名就是方法的名称,符合标识符的规则即可。

    参数列表就是传入方法的数据,比如:算两个整数的加法,需要参数--2个加数。

              返回值类型就是方法传出的数据(数据的类型),比如:算两个整数的加法,需要返回结果。

              方法中如果需要返回,使用return关键字。


   public int add(int a,int b){

     return a+b;

   }


  练习:

   在Point中加上两个方法,上下移动和左右移动。

   up()   - y发生改变

   left() - x发生改变

   并且在TestPoint中调用,向上移动2个坐标,并且先向右移动3个坐标。并且打印新的坐标。


  构造方法 - 用于创建对象的代码,一般都写初始化的代码。


  因为写的是类,调用的时候要用对象,如何由类得到对象呢? new + 构造方法。


  类都需要实例化成对象,因此,每个类都是必须有构造方法。


  JVM针对构造方法的机制: 如果类中没有定义构造方法,系统会自动加一个无参数的构造方法;如果写了构造方法,系统不再添加,因为已经有了。


  构造方法的语法:

    修饰符  类名(参数列表) throws Exception{


    }

   修饰符和throws可以不写。

   public Point(){ }


  构造方法和方法的两大区别:

   1 方法有返回值,构造方法没有返回值,包括void也没有。

   2 方法名可以自定义,构造名和类名必须一致。

   在同一个类中,构造方法可以写多个,但要求参数列表必须不同。(重载)


  面向对象的代码汇总:

   public class Point{    //类

     属性:     int age;

     构造方法: public Point(){  }

     方法:    public String test(int a)

                   { return "hello"; }

   }


   public class TestPoint{

      main(){

        Point p = new Point(); //构造方法的调用(创建对象)

        p.age = 30; //属性

        String s = p.test(3);//方法

      }

   }

  作业:

    1 写一个Student类,属性:姓名/学号/年龄;构造写两个;方法写三个: 获取学生姓名的,修改学生姓名的,显示学生信息(包括姓名/学号和年龄)。然后写一个TestStudent类测试。

    2 写一个商品Product类,属性:编号、名称和价格;构造写两个;方法写三个:修改价格,显示商品信息,比较两个商品价格的高低(高/低/相等)。然后写一个TestProduct类测试。





写一个类(名词性质),类中包括:

 public class 类名{

   属性;

   构造方法;

   方法;

 }

 调用类中, new 构造方法() 可以得到对象,用对象/引用. 调用里面的属性和方法。 new一下,点一下。

 Product类的方法:

   public void setPrice(double nPrice){

     if(nPrice<0){

       System.out.println("价格错误,修改失败");

     }else{

       price = nPrice;

     }

   }


/*

比较价格

*/

   public int comPrice(Product p){

     if(price>p.price){

       return 1;

     }else if(price==p.price){

       return 0;

     }else{

       return -1;

     }

   }


 this关键字


  所有的属性变量不能重名,在同一区域的局部变量不能重名,但属性和局部变量可以重名。

  在局部变量的作用区域之外,变量名代表属性,

  在局部变量的作用区域之内,代表局部变量,如果想使用属性,需要this. 调用。


  在构造方法中,可以用this()调用本类的其它构造。this()必须放在构造的第一行。


  this.可以调用本类的属性和方法;this()可以调用本类的构造。


  this()可以实现构造代码的复用。

  代码复用是软件开发中最常见的一种方式,就是代码只写一次,其它地方都是调用。

  其实,我们所有的API都是代码复用。


重载 - Overload

  当在一个类中,写上两个或者更多的构造时,自然形成了构造方法的重载。重载就是同名但参数不同。

  重载的特点:

        相同的方法名称,不同的参数列表,返回类型最好相同。

  重载的好处:

        就是让调用者更方便,只需要记住一个方法名就可以了。重载不会简化代码量。

       不是所有的方法都需要重载,只有执行相似功能的方法才可以重载。



Java参数传递


  java中的方法可以传递参数,参数的传递方法就是值传递


  参数有形参和实参,定义方法时写的参数叫形参,    真正调用方法时,传递的参数叫实参


  调用方法时,会把实参传递给形参,方法内部其实是在使用形参。



  参数传递的步骤:

   1 分配实参的空间,基本类型在栈中赋值,引用类型变量在栈中,指向堆中的对象。

   2 传递参数其实就是在栈中分配形参的空间,然后把栈中实参的值复制过来。

   3 在方法中使用形参,方法结束形参出栈(消失),只剩下实参。


方法的递归

  方法自己调用自己就叫递归。

  递归有可能会大幅简化代码的编写。

  递归要考虑性能问题,有些时候可以使用循环而不是递归。

  递归的使用原则:

  1 必须有退出条件。

  2 必须使问题变简单,而不是复杂化。


递归实例:

  public class TestN{

    public long f(long n){ //递归

      if(n == 1) return 1;

      return n*f(n-1);

    }

  public static void main(String[] args){

    TestN tn = new TestN();

    long res = tn.f(20);

    System.out.println(res);

  }

}


 int a =2 ;int b = 3; //不借助其它变量交换a和b

 a = a+b;// a=5 b=3

 b = a-b;// a=5 b=2

 a = a-b;// a=3 b=2




 封装 - 代码如果不做限制,很多属性值是无效的。封装就是为了保证属性值有效的技术。


  封装的步骤:

   1 先private(私有)修饰属性(常量不用私有),让属性在类外不能被调用,避免类外的赋值。

     另外要给属性一个合理的初始值。

   2 写public的方法对属性进行操作,一般都是set方法(写入)和get()方法(读取)。

   3 构造里面不要赋值,要调set方法赋值。


  虽然封装已经很严格,但是反射可以打破封装。



----------------------------------------------------------------------------------------------------------------------------------------

今天内容:

   (1)static关键字

   (2)继承

   (3)访问控制

   (4)final关键字


1.static关键字(重点)

1.1 基本概念

   通常情况下,属性和方法都属于对象层级,访问属性和方法时需要先创建对象再访问,

   每个对象都拥有自己独立的属性信息,

   但当使用static关键字修饰属性后,该属性就不再隶属于对象层级,而是提升类层级,被整个类创建的所有对象共享。


   对于static(静态的)修饰的属性和方法来说,

   虽然可以使用对象./类名.进行访问,但是绝大多数情况下都建议使用类名.访问。

   static关键字可以修饰属性/方法/语句块。


1.2 使用方式

对属性而言:

(1)对于非静态属性(无static)来说,每个对象都独立拥有一份,只能通过各个对象通过对象.访问,不能使用类名.访问

(2)对于静态属性来说,该类型的所有对象共享同一份,可以通过对象./类名.访问(两种皆可,一般用类的多)。

对方法而言: 

(3)非静态方法中可以访问静态属性,也可以访问非静态属性。

(4)静态方法中只能访问静态属性,不能访问非静态属性


如:

/*

详细解释this.的作用效果

*/

   class A{                   //类A

      public void show(){   // => public void show(A this)   成员方法

      }


      public static void main(String[] args){           //主方法

            A a = new A();  // => 创建对象,调用构造方法

            a.show(); // => show(a);   对象调用方法  从系统底层来说是将对象当作实参调入方法之中,对应于方法定义来说是将对象调入方法定义中作为形参。

      }

   }


1.3 类加载的方式(了解)


   类中使用static修饰的属性/方法/语句块都是随着类的加载而准备就绪,其中类加载的主要方式有:

   (1)当创建对象时会加载类信息。

   (2)当使用类名.访问static修饰的属性/方法/语句块时会加载类信息。

   (3)使用Class.forName()可以加载类信息(以后讲到)     


注意:

   只有当该属性/方法/语句块隶属于类层级被多个对象所共享时才能加static,否则不要随便加static关键字。


1.4 构造块和静态语句块(了解)

   完成构造方法之前的操作,例如调用数据库、接入网络什么的。

   在类体中使用{}括起来的语句块,叫做构造块,每次创建对象时都会执行一次构造块。

   在类体中使用static{}括起来的语句块,叫做静态语句块,只在类加载时执行一次。


1.5 单例设计模式

(1)基本概念

   在某些特殊场合中,某个类有且只能有一个对象,这样的类叫做单例类。

   使用单例类编程的模式就叫做单例设计模式


(2)实现方法

   a.私有化构造方法。

   b.创建并提供一个本类类型的对象,使用private和static修饰。

   c.提供一个公有的,使用static修饰的get方法负责返回本类对象。   


public class Singleton{


  //private static Singleton s = new Singleton();//饿汉型   创建并提供一个本类类型的对象,

                                                             用private static 来修饰

  private static Singleton s;   //懒汉型


  private Singleton(){     //私有化构造


  }

  public static Singleton getInstance(){   //提供一个公有化的   用static修饰的get方法来   返回本类类型。

    //return s ;

    if(null == s){

      s = new Singleton;

    }

    else{

      retutrn s;

    } 

  }

}




今天内容:

   (1)继承

   (2)访问控制

   (3)final关键字

   (4)对象创建的过程

   (5)多态


1.继承

1.1 继承的由来

学生类

   属性:学号、姓名、年龄

   行为:学习、吃饭、娱乐

教师类

   属性:工号、姓名、年龄

   行为:讲课、吃饭、娱乐


   由上面的类可知,有些属性和行为是完全相同的,此时就可以将相同的属性和行为提取出来封装到另外一个类中,叫做Person类,让学生类和教师类继承Person类即可。


Person类

   属性:姓名、年龄

   行为:吃饭、娱乐

学生类 继承 Person类

   属性:学号

   行为:学习

教师类 继承 Person类

   属性:工号

   行为:讲课


1.2 基本概念


   继承就是指从现有类中派生出新类,新类可以吸收现有类中的属性和行为,还可以增加自己独有的属性和行为,从而实现代码的复用。

   在java语言中使用 extends 来表达继承关系。

如:

   class Student extends Person{}

   其中Student类 叫做 子类/派生类

   其中Person类 叫做 父类/基类/超类


1.3 注意事项

(1)子类可以继承父类的主要内容有:

    a.可以继承父类中的属性,包括私有属性。

    b.可以继承父类中的方法,不包括 私有方法 和 构造方法

(2)当创建子类对象时,会自动调用父类中的无参构造方法,如果希望调用父类中的有参构造方法,则需要使用super关键字。

   无论子类中是否自定义构造方法,都会自动调用父类中的无参构造方法,用于初始化子类对象中的父类子对象。

(3)java语言中不支持多继承,也就是说一个子类只能有一个父类,但一个父类可以有多个子类

(4)并不是两个类中有相同的属性和方法时,就一定可以继承,必须满足条件:子类 is a 父类时,才能使用继承关系


1.4 super关键字的使用

(1)基本概念

    this关键字表示本类对象,可以使用this.来访问本类和父类的属性和方法。

    super关键字表示父类对象,可以使用super.来访问父类中的属性和方法。

(2)使用方式

    在构造方法中使用this()表示 调用本类的 构造方法,要求必须在构造方法的第一行出现

    在构造方法中使用super()表示 调用父类的 构造方法,要求必须在构造方法中第一行出现     

    this()和super()不可能同时出现,如果构造方法中啥也没写,则自动添加super()。


1.5 方法的重写/覆盖(override)


(1)方法重写的由来

    当子类从父类中继承下来的方法不足以满足子类的需求时,就需要对父类中的方法进行重写/覆盖,来满足子类的需求。


(2)方法重写的要求

   a.要求方法名、参数列表以及返回值类型都相同。

   b.要求子类重写方法的访问权限不能比父类的方法小。

   c.要求子类重写的方法不能抛出更大的异常。

   d.static修饰的方法重写以后还是static的。


1.6 继承的作用

  (1)实现了代码的复用,并且提高了程序的扩展性和可维护性。

  (2)继承是多态的前提条件。


2.访问控制

2.1 常用的访问控制符

   public - 表示公有的

   默认方式 - 表示默认的访问权限

   protected - 表示保护的

   private - 表示私有的


2.2 访问控制符对应的访问权限

   访问控制符   本类内部       子类      同一个包中的其他类      其他包中的类

--------------------------------------------------------------------------

    public        ok            ok               ok                 ok

    默认方式      ok            no               ok                 no

    protected     ok            ok               ok                 no

    private       ok            no               no                 no


总结:

    对于public修饰的属性/方法来说,无论在哪里都能访问。

    对于private修饰的属性/方法来说,只能在本类内部访问,其他都不能访问。

    一般来说,属性都使用private修饰,而方法都使用public修饰。


2.3 包

   包本质就是文件夹/目录,用于存放不同的java文件,可以避免文件同名而引发的错误,也可以对文件进行归类,便于管理。

   定义包的语法格式是:

       package 包名;

       package 包名1.包名2.包名3....;  用于实现目录的嵌套。


3.final关键字

3.1 基本概念

  final 翻译为 最终的,表示不可更改的意思。

  final关键字 可以修饰 类/方法/属性。


3.2 使用方式


   final关键字修饰类 表示该类不能被继承(断子绝孙类),如:String类和System类、Math类,该方式的作用在于避免滥用继承。


   final关键字修饰方法 表示该方法不能被重写,该方式的作用在于避免滥用重写。

        该方法可以被继承。


   final关键字修饰属性 表示该属性必须要被初始化,不能依赖默认方式初始化,而一旦初始化完毕之后则不能更改,

        该方式的作用在于避免属性值的意外修改。


3.3 final修饰属性可以初始化的位置有:

   (1)在定义属性的同时指定初始值。

   (2)在构造方法中指定初始值,但要求所有自定义构造方法中都要进行初始化。

   (3)在构造块中进行初始化。 


4.对象创建的过程

4.1 单个类创建对象的执行过程

  (1)将硬盘上的.class文件加载到内存中,该过程叫做类加载。

  (2)在类加载的过程中自动加载静态成员,包括静态属性和静态方法以及静态语句块。

  (3)在加载的过程中先执行静态语句块。

  (4)执行完毕静态语句块之后执行构造块(先父类后子类)。

  (5)再执行构造方法,也就是执行构造方法体中的语句(先父类后子类) 。 


4.2 单个类创建对象时属性的赋值次序

  (1)执行静态语句块中属性的赋值。

  (2)执行属性的定义以及初始化语句。

  (3)执行构造块中的语句。

  (4)执行构造方法体中的语句。

  (5)执行main方法创建对象后的语句。


作业:

   设计一个Girl类,属性有:姓名、年龄以及是否有男朋友,行为有:显示所有属性信息。

   设计一个Teacher类,属性有:姓名、年龄以及薪水,行为有:显示所有属性信息。

   先分别实现上述两个类,再将共性提取出来为一个Person类,修改上述两个类继承自Person类,在Gir类和Teacher类中实现对显示属性信息方法的重写。





今天内容:

   (1)对象创建的过程

   (2)多态

   (3)抽象类

   (4)接口


1.对象创建的过程

1.1 单个类对象创建的过程

   (1)将硬盘上的.class文件加载到内存中,这个过程就叫类的加载。

   (2)执行静态语句块,随着类的加载而准备就绪。

   (3)执行构造块。

   (4)执行构造方法体。


1.2 父子类对象创建的过程

   (1)将硬盘上的.class文件加载到内存中,这个过程就叫类的加载。

   (2)先加载父类,执行父类的静态语句块。

   (3)再加载子类,执行子类的静态语句块。

   (4)创建父类子对象,对父类子对象中的属性进行初始化,执行父类的构造块。

   (5)执行父类的构造方法体,实现父类子对象的创建过程。

   (6)创建子类对象,对子类对象中的属性进行初始化,执行子类的构造块。

   (7)执行子类的构造方法体,实现子类对象的创建过程。


对象创建的过程(new XX()):

   1 JVM去硬盘中找class文件,然后读入内存。

   2 进行类加载,先加载父类,后加载子类,同时执行分配static属性的内存空间,执行static语句块。

   3 给父类和子类的非静态属性分配内存空间,清空属性或清0。

   4 执行父类属性的初始化语句(如果声明的同时进行了赋值),否则就还是空或0。

   5 执行父类的语句块。

   6 执行父类的构造。

   7 执行子类属性的初始化语句(如果声明的同时进行了赋值),否则就还是空或0。

   8 执行子类的语句块。

   9 执行子类的构造。




2.多态(重中之重)

2.1 基本概念

   多态就是指同一种事物具有多种不同的形态。

Java中有几种多态:

   1 基本类型的多态 -- 本质就是基本类型的自动类型转换和自动装箱/解箱。(不是通常指的多态)

   2 方法多态  -- 方法的重写和方法的重载

   3 引用类型的多态 -- 本质就是引用类型的自动类型转换(子类对象自动转父类)

     也就是父类的引用指向了子类的对象,用父类的类型可以传入父类和子类的对象。父类引用可以表示父类对象和所有子类的对象。


   通常指的多态就是引用类型的多态。多态最大的作用就是: 设计方法时,可以用父类的类型代表父类和子类的所有对象


如:

   byte b = 4;  short s = 4;  int i = 4;

   宠物:猫/狗/鱼/乌龟/兔子/小强/... ...


2.2 语法格式

   父类类型 引用名 = new 子类类型();


   在编译阶段引用是父类类型的,但是程序运行起来之后却是子类类型的,最终调用的方法也是子类中重写的方法,从而实现多态。


2.3 多态的效果

   (1)当使用父类引用指向子类对象时,父类引用只能调用父类中的方法,不能直接调用子类中的方法,因为在编译阶段就报错。

   (2)当希望父类引用能调用子类的方法时,需要对父类引用进行强制类型转换,再调用。


2.4 父子类型之间的转换

   子类类型向父类类型转换时,只需要自动类型转换即可。

   父类类型向子类类型转换时,需要进行强制类型转换。

   引用类型的转换必须发生在父子类之间,否则编译阶段报错,而且父类引用必须转换为真正指向的子类对象类型,否则在运行阶段抛出异常,也就是产生错误。

   当需要发生强制类型转换时,应该先使用instanceof来判断引用名指向的真正类型是否和要转换的目标类型相同,如果是则返回true,此时放心强转,否则不要进行强转。

如:

   if(ps instanceof Student){   如果成立则返回true,否则返回false。

      ... ...

   }


2.5 多态的作用

如:

   public void show(){}   - 打印学生的所有信息

   public void show(){}   - 打印老师的所有信息

   public void show(){}   - 打印工人的所有信息


   public void show(Student s){}

   public void show(Teacher t){}

   public void show(Worker w){}


解析:

   Person p = new Student();

   Person p = new Teacher();

   Person p = new Worker();


   public void show(Person p){

      p.print();

   }


调用:

   Student s = new Student();

   show(s);                       => Person p = s;  => p.print() => Student类print

   Teacher t = new Teacher();

   show(t);                       => Person p = t;  => p.print() => Teacher类print

   Worker w = new Worker();

   show(w);                       => Person p = w; => p.print() => Worker类print


   多态的主要作用在于屏蔽不同子类对象之间的差异性,从而写出通用的代码,实现通用的编程效果,也便于程序后续的维护和扩展性。


3.抽象类

3.1 基本概念

  抽象类就是指使用abstract关键字修饰的类。

  抽象类不能实例化对象/创建对象/构造对象,但可以被继承。其意义就在于被继承。


3.2 抽象方法

  抽象方法就是指使用abstract关键字修饰的方法,并且该方法没有方法体,用分号结尾。

  语法格式:

      访问控制符 abstract 返回值类型 方法名称(形参1,形参2,...);


3.3 抽象类和抽象方法之间的关系

  (1)抽象类可以没有抽象方法,也可以有抽象方法。

  (2)拥有抽象方法的类必须被声明为抽象类。

  (3)抽象类中可以有普通/静态的方法。


3.4 抽象类的作用

  抽象类的主要作用在于被继承,而子类一旦继承抽象类之后就必须重写抽象类中的抽象方法,否则子类也变成抽象类。 


注意:

   抽象类虽然不能创建对象,但是有构造方法,为了子类创建对象时调用。


abstract 不能和final、static同时出现。


4.接口

4.1 基本概念

   黄金 属于金属,黄金属于货币,在java语言中支持单继承,因此黄金不能同时继承金属和货币,那么怎么办呢?

   在java中引出接口的概念,一个类可以同时实现多个接口。

   定义类使用class关键字,继承类使用extends关键字。

   定义接口使用interface关键字,实现接口使用implements关键字。

Java的接口用于解决多重继承问题。接口一般用于定义规范,交给子类实现。

4.2 注意事项

   (1)接口中的属性必须且只能是public static final,不写自动添加。

   (2)接口中的方法必须且只能是public abstract,不写自动添加。


4.3 类、接口之间的继承关系

    类和类之间的继承     单继承    使用extends关键字

    类和接口之间的继承   多继承    使用implements关键字

    接口和接口之间的继承 单继承    使用extends关键字


注意:

    对于默认访问方式的属性来说,在其他包的子类中是不能直接访问的,但是在同一个包中的子类是可以访问的。    







复习:

1.对象和类的基本概念

  对象就是个东西,万物皆对象。

  无论是何种对象,都会有  属性和行为。


  将对象的共性提取出来组成一个类,类中封装描述属性的成员变量,描述行为的成员方法。

  类是一种用户自定义的引用数据类型。


2.类的定义

  访问修饰符 class 类名{

       访问修饰符 数据类型 变量名 = 初始值;

       访问修饰符 返回值类型 方法名(形参列表){ 方法体; }

  } 

如:

  public class Person{

     private String name;

     public void show(){}

  }


3.创建对象

  类类型 引用变量名 = new 类类型();


4.构造方法

  class 类名{


      访问修饰符 类名(形参列表){ 构造方法体; }

  } 


  如果一个类中没有自定义构造方法,则系统会自动提供一个无参的默认构造方法。

  如果一个类型中出现了构造方法,无论是否有参数,系统都不在提供默认构造方法。


5.方法的重载

   在同一个类中,方法名相同,参数列表不同,返回值类型最好相同。

   调用者使用非常方便。

   System.out.println(char); ... ...


6.this关键字

   Person p1 = new Person();

   Person p2 = new Person();


   p1.show();  => show(p1);   

   p2.show();  => show(p2);


   当形参变量名和属性完全相同时,需要使用this.来进行区分

   this() - 表示调用本类的构造方法


7.封装

  (1)私有化属性;  (2)提供公有的get/set方法  (3)在构造方法中使用get/set方法


8.static关键字

   static关键字可以修饰属性/方法,从对象层级提升到类层级,虽然可以使用对象.调用,但是推荐使用类名.调用。

   static修饰的方法中 能访问static修饰的属性和方法,但是不能访问非static修饰的。

   非static修饰的方法中 可以访问static修饰的,也可以访问非static修饰的


   单例设计模式 - 懒汉式/饿汉式


9.继承

   继承就是从现有类中派生出新的子类,子类吸收现有类的属性和方法,还可以增加新的属性和行为,表示个性.

   使用extends关键字进行继承,java中支持单继承,不支持多继承。

   Student extends Person


   super() - 调用父类的无参构造方法

   super(实参) - 调用父类中的有参构造方法

   必须放在构造方法中的第一行,不可能和this同时出现


   this.调用本类的属性/方法以及从父类中继承来的属性和方法

   this()


   super.调用父类的属性/方法

   super() 


   方法的重写 

       要求方法名相同、返回值类型相同、参数列表也相同。

       不能抛出更大的异常

       权限不能更小


10.final关键字

   final修饰类/方法/属性。


   final修饰的属性可以初始化的位置:定义/构造方法中/构造块


11.多态

   父类类型 引用名 = new 子类类型();


   子类类型转换到父类类型自动转换完成

   父类类型到子类类型的转换 需要 进行 强制类型转换,进行判断

   父子类之间的转换

   instanceof 进行判断    true  false


   多态屏蔽不同子类之间的差异性,实现了通用的编程


12.抽象类

   使用abstract关键字修饰的类  不能创建对象,但是有构造方法

   使用abstract关键字修饰方法,并且没有方法体,使用分号结尾。


   被继承,要求子类去实现一些方法。


13.接口

   用于解决多继承的问题。

   interface关键字    implements


   类  继承  类   单继承   extends

   类  继承  接口  多继承  implements

   接口 继承 接口  单继承  extends


   接口中没有构造方法,接口中的所有属性都是自带 public static final

   接口中的所有方法自带 public abstract


   抽象类和接口之间的区别:

      a.关键字不同,class  和  interface

      b.抽象类中有构造方法,接口中没有构造方法

      c.抽象类支持单继承,接口支持多继承

      d.抽象类中的属性可以是普通的,但接口中都是自带public static final.

      e.抽象类中可以有普通方法,但是接口中都是自带public abstract.

      f.抽象类中增加方法可以不对子类产生影响,但是接口中只要增加方法,就一定

        会影响子类


接口和抽象类的区别:

    1 关键字不同,接口是interface,抽象类是class。

    2 继承方式不同,接口是多继承,使用implemnets关键字;抽象类是单继承,使用extends关键字。 

    3 接口中所有的属性都是public的常量,抽象类的属性可以随便。

    4 接口中没有构造方法的存在,抽象类一定有构造方法,但不能new,子类可以用super()调用。

    5 接口中的方法都是public abstract的,抽象类中可以有抽象方法,也可以有非抽象方法。

    6 接口有强制性,接口中的方法子类必须重写,否则就是抽象类;抽象类未必。

    7 定义规范,最好使用接口而不是抽象类。


--------------------------------------------------------------------------------


JAVA-面向对象