zoukankan      html  css  js  c++  java
  • java面向对象深入

    java面向对象深入

    大纲

    package与import

    package

    概述

    package存在的意义是防止命名冲突造成使用不便。

    package类似一个文件夹,文件夹内有各种文件。package与package的附属关系用“.”连接,类似父文件夹中的子文件夹。比如说 java.lang.String就是java文件夹中的lang文件夹中的String文件。java.io.InputStream则是java文件夹中的io文件夹中的InputStream文件。

    同一个文件夹内无法存在同名的文件,而不同名的文件夹里允许存在同名文件,因此不同文件夹(即不同package中允许出现相同class名)。

    为了便于管理大型软件系统中数目众多的类,解决类的命名冲突问题,Java 引入包(package)机制,提供类的多重类命名空间。 

    格式

    一般的命名为:公司域名倒写+功能名|模块名。

    package 语句作为 Java 源文件的第一条语句,指明该文件中定义的类所在的包。(若缺省该语句,则指定为无名包)。

    <span style="color:#cb4b16"> <span style="color:#770088">package</span> <span style="color:#0000ff">pkg1</span>[.<span style="color:#000000">pkg2</span>[.<span style="color:#000000">pkg3…</span>]];</span>

    例:

    <span style="color:#cb4b16"> <span style="color:#770088">package</span> <span style="color:#0000ff">com</span>.<span style="color:#000000">java01</span>.<span style="color:#000000">test</span>;</span>

    Java 编译器把包对应于文件系统的目录管理,package 语句中,用’.’来指明包(目录)的层次,例如使用语句: package com.java01 ,则该文件中所有的类位于.comjava01 目录下

    注意:

    • 不要定义与 jdk 相同的包,相同的类,否则会引起很多你觉得莫名其妙的问题

    • 写项目时都要加包,不要使用默认包。

    • com.oop和com.oop.test,这两个包没有包含关系,是两个完全独立的包。只是逻辑上看起来后者是前者的一部分。

    import

    如果一个类存在包名,则在其他包下使用该类时,必须使用全额限定名(简称全名或完整类名,com.java01.MyClass),编译器才能找到该类;也可以使用 import 在文件的开头引入要使用到的类。

    <span style="color:#cb4b16"> <span style="color:#770088">import</span> <span style="color:#000000">java</span>.<span style="color:#000000">util</span>.<span style="color:#000000">Scanner</span>;
     <span style="color:#770088">import</span> <span style="color:#000000">java</span>.<span style="color:#000000">io</span>.<span style="color:#981a1a">*</span>; <span style="color:#aa5500">//模糊匹配当前io包下所有类</span>
     <span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">ImportDemo</span> {
         <span style="color:#770088">public</span> <span style="color:#770088">static</span> <span style="color:#008855">void</span> <span style="color:#000000">main</span>(<span style="color:#008855">String</span>[] <span style="color:#000000">args</span>) {
             <span style="color:#000000">Scanner</span> <span style="color:#000000">sc</span><span style="color:#981a1a">=</span><span style="color:#770088">new</span> <span style="color:#000000">Scanner</span>(<span style="color:#000000">System</span>.<span style="color:#000000">in</span>); <span style="color:#aa5500">//因为使用import关键字导包,可以使用</span>
             <span style="color:#000000">java</span>.<span style="color:#000000">util</span>.<span style="color:#000000">ArrayList</span> <span style="color:#000000">list</span><span style="color:#981a1a">=</span><span style="color:#770088">new</span> <span style="color:#000000">java</span>.<span style="color:#000000">util</span>.<span style="color:#000000">ArrayList</span>(); <span style="color:#aa5500">//权限定名</span>
             <span style="color:#aa5500">//导入集合 注意:导入是不要导错包</span>
             <span style="color:#aa5500">//使用*,模糊匹配</span>
             <span style="color:#000000">File</span> <span style="color:#000000">file</span><span style="color:#981a1a">=</span><span style="color:#770088">new</span> <span style="color:#000000">File</span>(<span style="color:#aa1111">"D://test.txt"</span>);
             <span style="color:#000000">InputStream</span> <span style="color:#000000">isInputStream</span><span style="color:#981a1a">=</span><span style="color:#770088">new</span> <span style="color:#000000">FileInputStream</span>(<span style="color:#000000">file</span>);
         }
     }</span>

    不需要使用 import 的类有:

    1. 语言包 (java.lang)下的类 (String,System...)

    2. 同包下的类

    静态导入: import 语句不仅可以导入类,还增加了导入静态方法的功能

    <span style="color:#cb4b16"> <span style="color:#aa5500">//导入静态属性</span>
     <span style="color:#770088">import</span> <span style="color:#770088">static</span> <span style="color:#000000">java</span>.<span style="color:#000000">lang</span>.<span style="color:#000000">Math</span>.<span style="color:#000000">PI</span>;
     <span style="color:#770088">import</span> <span style="color:#770088">static</span> <span style="color:#000000">java</span>.<span style="color:#000000">lang</span>.<span style="color:#000000">System</span>.<span style="color:#000000">out</span>;
     <span style="color:#aa5500">//导入静态方法</span>
     <span style="color:#770088">import</span> <span style="color:#770088">static</span> <span style="color:#000000">java</span>.<span style="color:#000000">lang</span>.<span style="color:#000000">Math</span>.<span style="color:#000000">sin</span>;
     ​
     <span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">ImportDemo</span> {
         <span style="color:#770088">public</span> <span style="color:#770088">static</span> <span style="color:#008855">void</span> <span style="color:#000000">main</span>(<span style="color:#008855">String</span>[] <span style="color:#000000">args</span>) {
             <span style="color:#000000">out</span>.<span style="color:#000000">println</span>(<span style="color:#000000">PI</span>);
             <span style="color:#000000">sin</span>(<span style="color:#116644">1.1</span>);
         }
     }</span>

    总结

    • 如果想将一个类放入包中,在类的源文件首行使用package

    • 必须保证该类的 class 文件位于正确的目录下

    • 另外的类想访问的话:

      1. 写全名

      2. 引入

        • 模糊匹配(会将该包下所有用到的类引入进来),会降低编译速度,但是不会影响运行速度

        • 具体类名

        • 静态导入

      3. 同包下的类不需要导入

    JDK 中常用的包简单介绍:

    1. java.lang –语言包:语言中常用的功能,如:String、Math、System、Integer、Thread…

    2. java.util – 工具包:提供一些实用的工具类,如:容器(List、Set、Map…),日期类

    3. java.io – 输入输出包:提供操作读取文件的相关类,如:File、InputStream、OutputStream…

    4. java.net – 网络包: 操 作 远 程 资 源 的 类 , 如:InetSocketAddress、 DatagramPacket、 ServerSocket…

    5. java.sql – 数据库包:操作JDBC的类,Connection、Statement、ResultSet….

    垃圾回收机制(gc)

    概述

    Garbage Collection 垃圾回收机制

    每个程序员都遇到过内存溢出的情况,程序运行时,内存空间是有限的,那么如何及时的把不再使用的对象清除将内存释放出来,这就是GC要做的事。

    说起垃圾回收机制(GC),大部分人都把这项技术当做Java语言的伴生产物。事实上,GC的历史比Java久远,早在1960年Lisp这门语言中就使用了内存动态分配和垃圾回收技术。

    程序员们知道,jvm内存结构分为五大区域:程序计数器、虚拟机栈、本地方法栈、堆区、方法区。其中虚拟机栈、本地方法栈与程序计数器这3个区域随线程而生、随线程而灭,因此就不需要考虑过多内存垃圾回收问题,因为一个方法调用结束或者线程结束时,内存自然就跟随着回收了。

    我们就把重点放在方法区与堆区,这部分内存的分配和回收是动态的,正是垃圾收集器所需关注的部分。

    GC主要做了清理对象,整理内存的工作。

    不同语言下对象空间的释放:

    • 传统的C/C++语言,需要程序员负责回收已经分配内存。显式回收垃圾回收的缺点:

      1. 程序忘记及时回收,从而导致内存泄露,降低系统性能。

      2. 程序错误回收程序核心类库的内存,导致系统崩溃。

    • Java语言不需要程序员直接控制内存回收,是由JRE在后台自动回收不再使用的内存,称为垃圾

      回收机制(Garbage Collection)。

      1. 可以提高编程效率。

      2. 保护程序的完整性。

      3. 其开销影响性能。Java虚拟机必须跟踪程序中有用的对象,确定哪些是无用的。

    垃圾回收机制关键点:

    • 垃圾回收机制只回收JVM堆内存里的对象空间。

    • 对其他物理连接,比如数据库连接、输入流输出流、Socket连接无能为力

    • 现在的JVM有多种垃圾回收实现算法,表现各异。

    • 垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行。

    • 可以将对象的引用变量设置为null,暗示垃圾回收机制可以回收该对象。

    • 程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定。

    • 垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)。

    • 永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用。

    block与debug

    block

    块{},在java中自成作用域,可以分为

     静态代码块构造代码块普通语句块同步代码块
    声明位置 类中,方法外 类中,方法外 方法中 fynchronized(){}
    作用 整个类进行某些初始化操作(静态属性赋值...) 构造代码块是为对象初始化操作(为静态或非静态成员属性赋值...) 声明一些临时变量等.. 控制并发
    执行时机 类第一次加载时,只执行一次,如果多个静态块,从上倒下一次执行 创建对象时,执行构造器代码之前执行,如有多个,从上倒下一次执行 跟随方法执行 跟对方法执行

    注意:

    • 类第一次被载入时先执行static代码块;类多次载入时,static代码块只执行一次;static块经常用来进行static变量的初始化。

    • 是在类初始化时执行,不是在创建对象时执行。

    • 静态初始化块中不能访问非static成员。

    • 构造块被被编译到将要执行的构造器代码之前执行

    静态块,仅在类的第一次使用时加载。 构造块,先于构造器执行,每创建一个对象执行一次

    debug

    在学习或开发过程中,遇到bug是避免不了的,为了能够快速调试,可以使用debug调试工具。

    调试一个Java程序非常简单的,主要有设置断点、启动调试、单步执行、结束调试几步。

    debug界面窗口:

    1)设置断点

    2)启动调试

    Eclipse提供几种方式来启动程序(Launch)的调试,分别是通过菜单(Run –> Debug)、图标(“绿色臭虫”)、右键->Debug As。

    弹出提示,需要切换到调试(Debug)工作区,勾选“Remember my decision”,记住选择,则下次不再提示,然后点击【Yes】。

    3)单步执行

    主要使用前面讲过的几个视图进行调试,其中debug视图中的几个按钮有快捷键:

    Step Return(F7) : 表示退出当前方法,返回到调用层。

    Step Over (F6) : 表示运行下一行代码。

    Step Into (F5) : 表示进入当前方法。

    4)结束调试

    通过Terminate命令终止对本地程序的调试。

    面向对象-继承性

    继承

    “树上一只鸟树下两只兔子,请问几种动物 , 请问几种生物?” 这里面就存在了继承的概念。

    继承:子承父业

    继承的本质在于抽象。类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。

    继承的作用 : 使用继承可以提高代码的复用性。

    如何使用继承:

    父类|超类|基类:根据一些列子类抽象,抽取像的部分,定义在父类中

    子类|派生类:子类继承父类,有权使用父类中的内容,可以定义子类新增内容,所以说子类是父类的延续+扩展

    extends 关键字的意思是“扩展”。子类是父类的扩展。

    java 中使用 extends 关键字实现类的继承机制,语法规则:

    <span style="color:#cb4b16"> <span style="color:#981a1a"><</span><span style="color:#000000">modifier</span><span style="color:#981a1a">></span> <span style="color:#770088">class</span> <span style="color:#981a1a"><</span><span style="color:#000000">name</span><span style="color:#981a1a">></span> [<span style="color:#770088">extends</span> <span style="color:#981a1a"><</span><span style="color:#000000">superclass</span><span style="color:#981a1a">></span>]{} </span>
    <span style="color:#cb4b16"> <span style="color:#aa5500">//父类</span>
     <span style="color:#770088">class</span> <span style="color:#0000ff">Person</span>{
         <span style="color:#770088">public</span> <span style="color:#008855">String</span> <span style="color:#000000">name</span>;
         <span style="color:#770088">public</span> <span style="color:#008855">int</span> <span style="color:#000000">age</span>;
         
         <span style="color:#770088">public</span> <span style="color:#008855">void</span> <span style="color:#000000">sleep</span>(){
             <span style="color:#000000">System</span>.<span style="color:#000000">out</span>.<span style="color:#000000">println</span>(<span style="color:#aa1111">"休息"</span>);
         }
     }</span>
    <span style="color:#cb4b16"> <span style="color:#aa5500">//子类</span>
     <span style="color:#aa5500">//教师类</span>
     <span style="color:#770088">class</span> <span style="color:#0000ff">Teacher</span> <span style="color:#770088">extends</span> <span style="color:#000000">Person</span>{
         <span style="color:#770088">public</span> <span style="color:#008855">String</span> <span style="color:#000000">subject</span>;
         
         <span style="color:#770088">public</span> <span style="color:#000000">Teacher</span>() {
         }
         
         <span style="color:#770088">public</span> <span style="color:#008855">void</span> <span style="color:#000000">teach</span>(){
             <span style="color:#000000">System</span>.<span style="color:#000000">out</span>.<span style="color:#000000">println</span>(<span style="color:#aa1111">"传授知识"</span>);
         }
         
     }
     ​
     <span style="color:#aa5500">//学生类</span>
     <span style="color:#770088">class</span> <span style="color:#0000ff">Student</span> <span style="color:#770088">extends</span> <span style="color:#000000">Person</span>{
         <span style="color:#770088">public</span> <span style="color:#008855">String</span> <span style="color:#000000">school</span>;
         
         <span style="color:#770088">public</span> <span style="color:#000000">Student</span>() {
         }
         
         <span style="color:#770088">public</span> <span style="color:#008855">void</span> <span style="color:#000000">study</span>(){
             <span style="color:#000000">System</span>.<span style="color:#000000">out</span>.<span style="color:#000000">println</span>(<span style="color:#aa1111">"在知识的海洋畅游!"</span>);
         }
     }</span>

    注意:

    • 子类继承父类的成员变量和成员方法,但不继承父类的构造方法

    • java中只有单继承 ,没有像c++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。就像我们现实中,如果你有多个父母亲,那是一个多么混乱的世界啊。多继承,就是为了实现代码的复用性,却引入了复杂性,使得系统类之间的关系混乱。

    • java中的多继承,可以通过接口来实现

    • 如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。

    继承的特点:

    优点:

    • 通过继承可以简化类的定义,实现代码的重用|提高代码复用性

    • 可以更好的扩展程序

    • 子类一旦继承父类,可以有权使用父类中的成员,也可以扩展定义子类独有内容

    • java是单继承继承,实现简单

    缺点:

    • 子类与父类之间紧密耦合(耦合度高),子类依赖于父类的实现,子类缺乏独立性。

    • 不便于后期维护

    • 单继承一个子类只能有一个父类,不够灵活,不便于后期维护

    super关键字

    super

    super是指向父类的引用。

    super可以在子类构造器中调用父类某个构造器

    如果构造方法没有显示地调用父类的构造方法,那么编译器会自动为它加上一个默认的super()方法调用。如果父类由没有默认的无参构造方法,编译器就会报错,super()语句必须是构造方法的第一个子句。

    super可以用来区分子父类中同名成员

    如果不存在同名问题,可以直接在子类中调用父类内容,super默认省略

    如果存在同名问题,在子类中调用同名成员,默认this.恒源 调用当前子类同名成员,先要调用父类同名成员,必须定义为super.成员

    <span style="color:#cb4b16"> <span style="color:#aa5500">//父类</span>
     <span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">Animal</span> {
         <span style="color:#008855">int</span> <span style="color:#000000">eye</span> <span style="color:#981a1a">=</span> <span style="color:#116644">2</span>;
         <span style="color:#770088">public</span> <span style="color:#000000">Animal</span>(){
             <span style="color:#770088">super</span>();
             <span style="color:#000000">System</span>.<span style="color:#000000">out</span>.<span style="color:#000000">println</span>(<span style="color:#aa1111">"动物"</span>);
         }
         
         <span style="color:#770088">public</span> <span style="color:#008855">void</span> <span style="color:#000000">run</span>(){
             <span style="color:#000000">System</span>.<span style="color:#000000">out</span>.<span style="color:#000000">println</span>(<span style="color:#aa1111">"动物有不同走路方式"</span>);
         }
         
         <span style="color:#770088">public</span> <span style="color:#770088">static</span> <span style="color:#008855">void</span> <span style="color:#000000">main</span>(<span style="color:#008855">String</span>[] <span style="color:#000000">args</span>) {
             <span style="color:#000000">Bird</span> <span style="color:#000000">b</span> <span style="color:#981a1a">=</span> <span style="color:#770088">new</span> <span style="color:#000000">Bird</span>();
             <span style="color:#000000">b</span>.<span style="color:#000000">run</span>();
         }
     }
     <span style="color:#aa5500">//子类</span>
     <span style="color:#770088">class</span> <span style="color:#0000ff">Bird</span> <span style="color:#770088">extends</span> <span style="color:#000000">Animal</span>{
         <span style="color:#770088">public</span> <span style="color:#000000">Bird</span>(){
             <span style="color:#770088">super</span>();
             <span style="color:#000000">System</span>.<span style="color:#000000">out</span>.<span style="color:#000000">println</span>(<span style="color:#aa1111">"鸟类"</span>);
         }
     ​
         <span style="color:#770088">public</span> <span style="color:#008855">void</span> <span style="color:#000000">run</span>() {
             <span style="color:#770088">super</span>.<span style="color:#000000">run</span>(); <span style="color:#aa5500">// 通过super可以用父类方法和属性</span>
             <span style="color:#000000">System</span>.<span style="color:#000000">out</span>.<span style="color:#000000">println</span>(<span style="color:#aa1111">"鸟是飞飞飞飞飞飞"</span>);
             <span style="color:#000000">System</span>.<span style="color:#000000">out</span>.<span style="color:#000000">println</span>(<span style="color:#aa1111">"鸟类有"</span><span style="color:#981a1a">+</span><span style="color:#770088">super</span>.<span style="color:#000000">eye</span><span style="color:#981a1a">+</span><span style="color:#aa1111">"只眼睛"</span>);
         }
        
     }</span>

    Bird--> Animal --> Object 图形分析如下

    构造方法调用顺序:

    • 根据super的说明,构造方法第一句 总是:super(…)来调用父类对应的构造方法。

    • 先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直到当前子类为止。

    this和super之间的区别

    相同点:

    1. this和super都能用来调动其他共构造器,都要在首行出现

    2. this和super都可以用来区分同名问题,不区分同名时候可以省略

    3. this和super都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句

    块。

    不同点:

    1. this(参数)构造器第一行调用本类中其他构造器,super(参数)构造器第一行调用父类中某个构造器

    2. this用来区分成员和局部同名问题,super用来区分子父类中同名问题

    注意:

    • this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会过。

    • 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字

    重写与final关键字

    重写Override

    父类的功能实现不满足子类的要求,可以在子类中按需改写,这就是方法的重写。

    实现重写的三个条件:

    • 不同的两个类

    • 继承关系|实现关系

    • 方法签名相同

    @Override:注解,强制检查是否为重写方法

    注意:

    • 子类重写的方法会对父类的方法进行屏蔽。

    • 当子类对象调用时,会调用子类中重写的方法,子类没有找父类。

    <span style="color:#cb4b16">public class OverrideTest {
    	public static void main(String[] args) {
    		Sicong sicong=new Sicong();
    		sicong.getMoney(); //调用子类中重写方法
    	}
    }
    //父类
    class Jianlin{
    	public void getMoney(){
    		System.out.println("先定一个小目标,赚他个一个亿");
    	}
    }
    //子类
    class Sicong extends Jianlin{
    	@Override  //强制检查是否为重写方法
    	public void getMoney(){
    		super.getMoney();//在父类的原赚钱方法上扩展新功能,老功能不变
    		System.out.println("我认识的人都没我有钱");
    	}
    }
    </span>

    重写的三个"=" : “==”:方法名、形参列表相同。

    “≤”:抛出的异常类型与返回值类型,返回值类型如果为基本类型必须相同,引用数据类型子类小于等于父类。

    “≥”:访问权限,子类大于等于父类。

    以下修饰符、修饰的内容不能重写:

    1. private修饰的方法不能被重写

    2. final修饰的方法不能被重写

    3. static修饰的方法不能被重写(子类如果出现和父类静态方法同名情况,那么子类中的方法也必须为静态的)

    final关键字

    final 表示最终的。

    final可以用来修饰变量,方法,类。

    修饰变量:变量一旦被初始化便不可改变,相当定义了一常量。

    <span style="color:#cb4b16">final int x=3;
    //x=4; 常量不能改变
    </span>

    修饰方法 : final方法是在子类中不能被覆盖的方法

    <span style="color:#cb4b16">final void eat() { … }
    </span>

    修饰类,表示该类不能被继承

    <span style="color:#cb4b16">final class Person{ … }
    </span>

    Object类

    Object 类是所有 Java 类的根基类

    如果在类的声明中未使用 extends 关键字指明其基类,则默认基类为 Object 类

    toString(): 当打印对象的引用时,默认调用toString()方法

    • 默认返回:包名+类名+@+哈希码(根据对象的内存地址生成,唯一不重复)

    • 可以重写,实现义字符串的形式返回对对象(打印对象所有成员属性的值)

    <span style="color:#cb4b16">User p1=new User("张三",20);
    System.out.println(p1);
    //相当于
    System.out.println(p1.toString());
    </span>

    equals:比较相等是否相等**

    • 默认地址比较(”第一个盒子的比较”)

    • 重写可以是实现比较两对象的内容是否一致

    <span style="color:#cb4b16"> object1.equals(object2) 
     如 : p1.equals(p2)
    • 比较所指对象的内容是否一样,具体看equals的方法重写
     object1 == object2
     如:p1==p2
    • 比较p1和p2的值即内存地址是否相等,即是否是指向同一对象。
    </span>

    注意:自定义类须重写equals(),否则无法实现比较其内容

    <span style="color:#cb4b16">class User{
    	String name;
    	int age;
    	public User() {
    		// TODO Auto-generated constructor stub
    	}
    	public User(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
        //重写toString
        @Override
    	public String toString() {
    		return "User [name=" + name + ", age=" + age + "]";
    	}
        //重写equals
    	@Override
    	public boolean equals(Object obj) {
    		if (this == obj)
    			return true;
    		if (obj == null)
    			return false;
    		if (getClass() != obj.getClass())
    			return false;
    		User other = (User) obj;
    		if (age != other.age)
    			return false;
    		if (name == null) {
    			if (other.name != null)
    				return false;
    		} else if (!name.equals(other.name))
    			return false;
    		return true;
    	}
    }
    </span>
  • 相关阅读:
    fdisk 分区
    fdisk 添加逻辑分区
    centos7 bond0 双网卡配置
    查看centos7启动项
    本地yum源安装docker
    cobbler Ubuntu16.04 安装
    docker-ce-17.03.2 离线安装RPM包
    day14 生成器的进阶
    day13迭代器与生成器
    day12闭包,装饰器
  • 原文地址:https://www.cnblogs.com/lezijie/p/12916845.html
Copyright © 2011-2022 走看看