Java基础之《类和对象》

对象和类的概念
  Java是纯面向对象语言
  类是用于描述同一类的对象的一个抽象的概念,类中定义了这一类对象所因具有的
  静态属性和动态属性(也叫方法)
  静态属性和成员变量是一回事
  对象是类的具体的实例 对象和实例是同一回事

类之间的关系
  关联关系(一个类的方法的参数是另一个类的对象)
  继承关系(一般和特殊)
    什么什么是一种什么什么(游泳运动员是一种运动员)
  实现关系(接口)
    具体的方法怎么去实现
  多态
  小结
  0)不应该考虑第一步干嘛第二步干嘛
  1)考虑在这个问题里面有哪些类和对象
  2)这些类和对象有哪些属性和方法
  3)类和类之间的关系

Java类的定义
  在Java程序中“万事万物皆对象”
  对象可以看成是静态属性(成员变量)和动态属性(方法)的封装体
  类是用来创建同一类型的对象的“模板”,在一个类中定义了该类对象所
  应具有的成员变量以及方法。
  成员变量=属性 方法=函数
  编软件苦苦追求的境界
    reusable可重用性
    extensibility可扩展性
    维护和替换更加方便
    ...
  组件—比对象更高的层次上的抽象(二进制级别)
    面向组件的编程(EJB、Web Service、CORBA、COM、...)
  服务导向架构(Service-Oriented Architecture,SOA)
    简单理解,SOA是一个架构,将程序封装成一个模块或组件,对外暴露一个接口供
    调用,接口的通讯必须使用标准的(http、XML、SOAP等)

  成员变量Java默认会对其初始化(成员变量和局部变量的重要区别)
    byte :0
    short :0
    int :0
    long :0L
    char :'\u0000'
    float :0.0F
    double :0.0D
    boolean :false
    所有引用类型 :null
  Java语言中除基本类型之外的变量都称之为引用类型
  Java中的对象是通过引用对其操作的
  java中的基本数据类型占一个内存块。而引用数据类型占两个内存块,一个内存块用来
    存放相关的变量名(存在栈内存中),而另外一个内存块则存放了该变量的值(
    存在堆内存中),访问该变量时,通过变量名找到其在堆内存中的值
  引用类型就是在栈里开了两个内存块,其中一个指向堆内存

  如何在内存中区分类和对象
    类是静态概念,放在代码区
    对象是new出来的,位于堆内存,类的每个成员变量在不同的对象中都有不同的值(除了静态变量)
    但是方法只有一份,执行的时候才占用内存,方法不调用就是一堆代码,只有执行的时候才会占用内存

  引用
    以后一提引用,一提到对象,脑子里立刻浮现一小块内存指向一大块内存

构造函数
  构造方法是用来初始化对象的函数
  构造方法与类同名且没有返回值(不能写void)
  main方法必须写在和文件名相同的类里面(主类)
  当不写构造方法,编译器会默认使用空的构造方法,将成员变量初始化

约定俗成的命名规则
  Java里约定俗成,类名首字母大写
  变量名和方法名首字母小写
  运用驼峰标识(后面的单词的首字母都大写)

一个.java文件里可以定义多个类,但java里主类的名称(main函数所在的类)和.java文件的文件名要一样

对象的创建和使用
  内存分析
  方法中值传递,形参实参是基本数据类型,在方法中把形参值给改了,不能改变实参是基础类型变量的值,因为它是copy了实参的值
  方法中值传递,形参实参是引用变量,在方法中调用这个对象的方法,可以改变实参的成员变量
    如果形参在方法里被指向new出来的新对象,不会改变实参指向的对象
  形参和局部变量同等对待,也是分配在栈空间
  方法调用完后,为这个方法分配的局部变量(或形参)自动消失
  一个方法,除非有static,否则要用对象去调用它
  返回值
    返回值在内存中也分配有一个临时的存储空间,它没有名字,当返回值返回后方法运行结束,这个临时空间随之消失
  内存分析好处:对以后理解内存里面连接池、单例模式、多例模式有莫大的好处

方法的重载
  方法的重载是指一个类中可以定义相同名字,但参数不同的多个方法。Java里方法重载看形参的个数和类型,不看返回值类型
  重载就是方法名都一样,就是参数不一样,因为调用方法时可以不用返回值
  与普通方法一样,构造方法也可以重载

对象的创建和使用-复习
  必须使用new关键字创建对象
  使用对象引用.成员变量来引用对象的成员变量
  使用对象引用.方法(参数列表)来调用对象的方法
  同一个类的每个对象有不同的成员变量存储空间
  同一个类的每个对象共享该类的方法(非静态方法)

返回值2
  返回值是一个Point类,严格来讲指的是它返回一个Point对象,或者
  更严格的它返回的是一个Point对象的引用
  返回值会存在一个临时的内存区域里面(叫什么名我们不去管它),这块
  区域的内容和return后面的变量是一样的

形参
  形参等同于局部变量,在方法执行完后立即消失
  形参是在方法中根据方法执行过程赋值给方法的成员变量

this关键字
  this关键字是对当前对象的引用
  使用this可以处理方法中成员变量和参数重名的情况
  当确定不了一个变量指的是你声明的哪个变量的时候,找离它最近的声明

return this
  return this返回this的内容,this指向它自身,那么返回值所在的临时内存区域也指向它
  所以可以有这样的用法:leaf.increament().increament().print();

static关键字
  static成员变量,属于类不属于某个对象,它是该类所有对象公用的成员变量(只有一份),在第一次使用时初始化
  static方法,静态方法直接用类名来调用,不能直接访问非静态的成员,可以通过对象引用或类名访问静态成员
  不管是用对象引用类的静态变量,还是用类名访问静态变量,他们所指向的是同一块内存
  静态变量可以用来记数

package和import语句
  包提供类的多重类命名空间
  如果把一个类放到包里面,第一句话写package
  //写这个package语句的java文件必须位于包的层级下面,和包的层次完全一样
  编译出来的class文件位置必须要放在这个包的层次下
  Java编译器把包,对应于文件系统的目录管理,package语句中,用“.”来指明包的层次,例如:package com.sxt;
    则该文件中所有的类位于.\com\sxt目录下
  DOS下执行需要在.这个目录下执行:java com.sxt.Cat
  执行一个类需要写全包名

  import语句用于引入包中的类
  import引入包的java文件(class文件),要和被引入包最上层在一起,例如要能找到com目录
  class文件的最上层包的父目录位于classpath下,否则编译时找不到包
  每一个project应该有自己的classpath,和其它classpath不共享
  可以不需要用import语句直接使用java.lang包中的类
  访问位于同一个包中的类不需要引入

  Java\jdk1.8.0_20\jre\lib\rt.jar java运行时 右键rar打开
  java.lang language-包含一些java语言的核心类,如String、Math、Integer、System、Thread提供常用功能
  java.net-包含执行与网络相关的操作的类
  java.io-包含能提供多种输入/输出功能的类
  java.util-包含一些使用工具类,如定义系统特性、使用与日期日历相关的函数等

  把自己的类打成jar包
  jar -cvf test.jar *.*
  jar -cvf hello.jar ./*(打包当前目录下的所有文件包含子目录)
  可以把jar包当成一个路径设到环境变量classpath里面

访问控制

类的继承
  java中使用extends关键字实现类的继承机制
  通过继承,子类自动拥有了基类的所有成员(成员变量和方法)
  java只支持单继承,不允许多继承

  继承:
  private 只有类内部的成员方法才能访问,子类不能直接访问基类的private成员变量,但可以通过基类的set、get方法访问
  default 又叫包权限,同一个包里面的其它类能访问default类的成员变量,子类不能访问
  protected 同一个包内能访问,它的子类也能访问
  public 任何地方都可以访问
  在heap空间,子类对象包含了一个父类的对象
  修饰:
  对于class的权限修饰只可以用public和default
  public类可以在任意地方被访问
  default类只可以被同一个包内部的类访问

  private和protected修饰calss在内部类中使用

方法的重写
  在子类中可以根据需要对从基类中继承来的方法进行重写
  重写方法必须和被重写方法具有相同方法名称、参数列表和返回值
  重写方法不能使用比被重写方法更严格的访问权限

  重载overload  重写overwrite/override  这两个是不同的
  子类重写了父类的方法后,子类的对象调用的是自己重写的方法

  在java类中使用super来引用基类的成分

  子类的构造的过程中必须调用其基类的构造方法
  子类可以在自己的构造方法中使用super(argument_list)调用基类的构造方法
      也可以使用this(argument_list)调用自己这个类的另外一个构造方法
      如果调用了super,必须写在子类构造方法的第一行
  如果子类的构造方法中没有显示地调用基类构造方法,则系统默认调用基类无
      参数的构造方法
  如果子类构造方法中既没有显示调用基类构造方法,而基类中又没有无参的构造
      方法,则编译出错

Object类
  Object类是所有Java类的根基类,所有Java类的老祖宗
  如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类

  clone()方法,把自己克隆一份
  finalize()方法,类似于C++的析构函数,由垃圾收集器回收对象之前调用
  getClass()方法,涉及到Java里面非常重要的一个机制——反射机制,getClass拿到
    的是自己编译好的Class文件
  hashCode()方法,返回这个对象的hash编码

  toString()方法返回类名+@+哈希值
  在进行String与其它类型数据(包括基本数据类型和引用类型)的连接操作时,将自动调用该对象的toString()方法

  equals()方法,继承下来默认是比较两个引用变量是否指向同一个对象 要重写
  JDK提供的一些类,如String、Date等重写了equals()方法,两个引用变量是同一类对象的引用(且成员变量值相等)就认为是相等的
  普通两个引用变量 c1 == c2 比较的是引用的对象地址,除非指向同一个对象否则肯定不相等

对象转型(casting)
  一个基类的引用类型变量可以"指向"其子类的对象
  一个基类的引用不可以访问其子类对象自己的成员和方法
  可以使用:引用变量 instanceof 类名 来判断该引用型变量所"指向"的对象是否属于
  该类或该类的子类
  instanceof做探测的是这个对象实际当中是什么类型,不是看引用把它看成什么样
  父类引用指向子类对象,它看到的只是作为父类那部分所拥有的属性和方法,作为子类那部分的看不找
  子类的对象可以当成基类的对象来使用称作向上转型,反之称作向下转型

多态
  动态绑定,也叫迟绑定,也叫多态
  动态绑定是指“在执行期间(而非编译期间)”判断所引用对象的实际类型,根据
  其实际的类型调用其相应的方法。
  基类的引用,指向子类的对象,调方法的时候,只要方法重写了,调什么方法看new的对象
  方法只是从磁盘加载到内存的一段代码,父类引用指向子类对象,父类引用调用方法时,
    是根据实际对象类型来确定的,实际new的什么类,就调用什么类的方法
  只有在运行期间,new出对象来,才能够确定父类对象里指向方法的指针,指向子类重写的方法还是
    自己的方法,所以叫动态绑定
  动态绑定,帮助程序的可扩展性达到了极致

  多态的必要条件
  1 要有继承
  2 要有重写
  3 父类引用指向子类对象

抽象类
  用abstract关键字修饰
  含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,不能用它来new一个
  对象,抽象方法必须被重写
  在基类中该方法没有实现的意义,因为子类必定要重写它,所以用abstract申明为
  抽象方法,相当于C++里面的纯虚函数
  abstract的类是“残缺不全”的类,所以必须被继承,abstract的方法只是一个标记,没有实现
  所以必须被重写

final关键字
  final的变量的值不能被改变
    final的成员变量
    final的局部变量(形参)
    一旦形参被传进来之后,在方法里面不允许被改变,传引用就是不能改变它指向的对象
  final的方法不能被重写
  final的类不能被继承

接口
  接口(interface)是抽象方法和常量值的定义集合
  接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有
  变量和方法的实现
  接口特性
    接口里成员变量的属性默认是public static final,也只能是public static final
    这是为了解决C++的多继承问题,static变量属于类不属于对象
    接口里只能定义抽象方法,接口里的方法只有声明没有定义,默认是public,也只能是public
    接口可以继承其它的接口,并添加新的属性和抽象方法
    定义类时用interface代替class,在接口里不用写abstract,所有的方法都是abstract
    接口实现了java里的"多继承",一个类可以实现多个接口,也隐含着多态
    定义一个接口类型的变量,指向继承了它的类的对象,与继承关系类似,接口与实现类之间存在多态性
    接口和接口之间也可以相互继承

  接口命名
  什么什么able,可以怎么怎么样的Cloneable、Comparable

定义Java类的语法格式
< modifier> class < name> [extends < superclass>]
[implements < interface> [,<interface>]* ] {
< declarations>*
}

接口之间可以相互继承

异常
  Java异常指运行期出现的错误
  观察错误的名字和行号最重要
  程序里出现异常的时候日志里是,从出现异常的这个点一层一层往外吐

Java异常概念
  异常是由方法运行错误后抛出的,只有调用了这个方法后才可能抛出异常
  如果一个方法运行时抛出异常:
  1)Java运行时系统默认是把抛出的异常对象里面包装的信息打印到控制台上(我们不捕捉)
  2)我们用try  catch语句捕捉到这个异常后进行处理
  2.1)如果catch语句里面不写任何内容,异常处理就是空白的
  2.2)ae.printStackTrace();  把错误的堆栈信息打印出来
  catch后面定义的异常对象是由Java运行时系统帮你填充好的,只要程序一出错这个对象就自动初始化了

  问题:方法如何抛出异常?
  方法声明里会有throws XXXXException
  在方法体里面判断会throw new XXXXException对象

  运行期间出现错误以后:
  Java首先会找catch相应的代码,看看有没有人捕捉这种异常
  如果有人catch,就跳到那个地方去处理它,可以有自己的处理
  如果没有人catch,就把信息打印到控制台上

Java异常的分类
  Throwable可被抛出的(所有异常的根类)
   |- Error系统出错
   |- Exception能处理的错误(必须处理)
       |- RuntimeException运行时错误,可以不处理的
   ...

  Error:系统错误问题,处理不了
  Exception:可以处理的异常
  RuntimeException:一类特殊的异常,产生的比较频繁,一般不处理

异常的捕获和处理
  Exception所有异常类的父类,其子类对应了各种可能出现的异常事件
  需要用户显示的声明或捕捉

  不是RuntimeException的异常必须得逮它,必须得写try catch
  一个try后面可以跟多个catch
  try {
  //可能抛出异常的语句
  } catch {SomeException1 e)
  {
  ...
  } catch {SomeException2 e)
  {
  ...
  } finally {
  //finally段的代码无论是否发生异常都会执行
  ...
  }

  当异常发生时,程序会终止当前流程,根据获取异常的类型去执行相应的catch代码段
  然后执行finally中的语句,当某个语句一旦出错后面的语句绝对不可能执行了
  通常在finally语句中可以进行资源的清除工作,如:关闭打开的文件、删除临时文件等

  问题:如果有两个try catch finally语句块,第一个try里面报错了,第二个try还会执行吗?
  答:多个try catch finally语句块不会互相影响

  问题:关于return在try和finally里面的问题,返回的值是哪个?
  答:http://www.cnblogs.com/aigongsi/archive/2012/04/19/2457735.html

  如果异常自己处理不了,就往外抛,由调用它的上一级处理
  如果一个方法运行时抛出异常2:
  1)自己不处理这个异常,不用写try  catch语句
  2)在方法声明后面往上抛这个异常throws XXXXException
    void f() throws IOException { };

  如果一直抛,到main方法继续往外抛,由Java运行时系统处理

一个图五个关键字
  图:Java异常分类
  关键字:try  catch  finally  throw  throws

throw自己定义抛异常
  逮异常的时候首先逮小的然后再逮大的
  在一个try语句块中,基类异常的捕获语句不可以写在子类异常捕获语句的上面

  使用自定义异常:
  1.通过继承java.lang.Exception类声明自己的异常类
  2.在方法适当的位置生成自定义异常类的实例,并用throw语句抛出
  3.在方法的声明部分用throws语句声明该方法可能抛出的异常

  当一个方法内部抛出异常之后(throw异常对象),方法到此结束,后面的语句是不会执行的!!
  外部对异常的捕获:
  1)RuntimeException可以不逮,Exception必须要逮
  2)如果是RuntimeException,我们不逮它,Java运行时系统默认打印到控制台上(同时程序结束)
  3)如果用try catch捕获异常,try语句块中发生异常的这句语句后面的语句不会执行
     只要没有return,外部程序在catch处理完异常后,程序继续往下走

异常和继承之间的关系
  注意:重写方法需要抛出与原方法所抛出异常类型一致异常或不抛出异常
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值