2-JavaObjectOriented

2019-10-18  本文已影响0人  Goinhn

Java面向对象设计

类与对象、封装、构造方法

类与对象的关系:
类是对一类事物的描述,是抽象的。对象是一类事物的实例,是具体的。类是对象的模板,对象是类的实体。

类的定义
public class ClassName{
    成员变量
    成员方法
}

成员变量定义的时候有其初始化的默认值:

在这里插入图片描述

封装

访问数据通过指定的方式
private:

  1. private是一个权限修饰符,代表最小权限。
  2. 可以修饰成员变量和成员方法。
  3. 被private修饰后的成员变量和成员方法,只在本类中才能访问。

this:
this代表所在类的当前对象的引用(地址值),即对象自己的引用。

构造方法
  1. 如果你不提供构造方法,系统会给出无参数构造方法。
  2. 如果你提供了构造方法,系统将不再提供无参数构造方法。
  3. 构造方法是可以重载的,既可以定义参数,也可以不定义参数。
标准代码--JavaBean

JavaBean是 Java语言编写类的一种标准规范。
符合 JavaBean 的类,要求类必须是具体的和公共的,并且具有无参数的构造方法,提供用来操作成员变量的 set 和 get 方法

常用API

API

应用程序编程接口

匿名对象

创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。
应用场景:

static关键字

关于 static 关键字的使用,它可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调用了。

在这里插入图片描述
方法区中只有一块区域是用来保存静态区的
静态代码块:
给类变量进行赋值
Object类

java.lang.Object类是Java语言中的根类,即所有类的父类。它中描述的所有方法子类都可以使用。在对象实例化的时候,最终找的父类就是Object。
如果一个类没有特别指定父类,那么默认则继承自Object类

Objects类

java.util.Objects类
在JDK7添加了一个Objects工具类,它提供了一些方法来操作对象,它由一些静态的实用方法组成,这些方法是null-save(空指针安全的)或null-tolerant(容忍空指针的),用于计算对象的hashcode、返回对象的字符串表示形式、比较两个对象。

在比较两个对象的时候,Object的equals方法容易抛出空指针异常,而Objects类中的equals方法就优化了这个问题。
//内部调用equals方法
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}

Scanner类

一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。
public final class Scanner
extends Object
implements Iterator<String>

     String input = "1 fish 2 fish red fish blue fish";
     Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
     System.out.println(s.nextInt());
     System.out.println(s.nextInt());
     System.out.println(s.next());
     System.out.println(s.next());
     s.close(); 

扫描器所使用的默认空白分隔符通过 Character.isWhitespace 来识别。不管以前是否更改,reset() 方法将把扫描器分隔符的值重置为默认空白分隔符。
**若没有外部同步,则 Scanner 的多线程使用是不安全的。 **
除非另行说明,否则将一个 null 参数传递到 Scanner 的任何一个方法中都将抛出NullPointerException。
默认情况下扫描器会将数字解释为十进制形式,除非已经使用 useRadix(int) 方法设置了不同的基数。不管以前是否更改,reset() 方法将把扫描器的基数重置为10 。

Random类

此类的实例用于生成伪随机数流。
public class Random
extends Object
implements Serializable

详细
空参数

public int nextInt() {
   return next(32);
 }

带有参数
返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值。nextInt 的常规协定是,伪随机地生成并返回指定范围中的一个 int 值。所有可能的 n 个 int 值的生成概率(大致)相同。Random 类按如下方式实现 nextInt(int n) 方法:

public int nextInt(int n) {
     if (n<=0)
        throw new IllegalArgumentException("n must be positive");

     if ((n & -n) == n)  // i.e., n is a power of 2
         return (int)((n * (long)next(31)) >> 31);

     int bits, val;
     do {
         bits = next(31);
         val = bits % n;
     } while(bits - val + (n-1) < 0);
     return val;
  }
ArrayList类

java.lang.Object
继承者 java.util.AbstractCollection<E>
继承者 java.util.AbstractList<E>
继承者 java.util.ArrayList<E>
size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。add 操作以分摊的固定时间 运行,也就是说,添加 n 个元素需要 O(n) 时间。其他所有操作都以线性时间运行(大体上讲)。
每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。
此实现不是同步的
所有已实现的接口:
Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess

存储基本类型使用包装类型

在这里插入图片描述
String类

java.lang.Object
继承者 java.lang.String
所有已实现的接口:
Serializable, CharSequence, Comparable<String>

public final class String
extends Object
implements Serializable, Comparable<String>, CharSequence

字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。

String 类包括的方法可用于检查序列的单个字符、比较字符串、搜索字符串、提取子字符串、创建字符串副本并将所有字符全部转换为大写或小写。大小写映射基于 Character 类指定的 Unicode 标准版。

Java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。字符串转换是通过 toString 方法实现的,该方法由 Object 类定义,并可被 Java 中的所有类继承。有关字符串串联和转换的更多信息,请参阅 Gosling、Joy 和 Steele 合著的 The Java Language Specification。

Arrays类

public class Arrays
extends Object

Math类

java.lang.Object
继承者 java.lang.Math
public final class Math
extends Object

Date类

java.lang.Object
继承者 java.util.Date
public class Date
extends Object
implements Serializable, Cloneable, Comparable<Date>

DateFormat类

java.text.DateFormat
由于DateFormat为抽象类,不能直接使用,所以需要常用的子类java.text.SimpleDateFormat


在这里插入图片描述

public String format(Date date):将Date对象格式化为字符串。
public Date parse(String source):将字符串解析为Date对象。

继承

is-a关系

继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。
优点:

  1. 提高代码的复用性。
  2. 类与类之间产生了关系,是多态的前提。

成员变量:
访问重名变量使用super关键字
封装提供getter setter方法
成员方法:
访问重名父类方法需要使用SUPER关键字
调用本类重名方法为重写(Override)
方法重写 :子类中出现与父类一模一样的方法时 (返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。
注意事项:

  1. 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
  2. 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。

父类空间优于子类对象的产生
super :代表父类的存储空间标识(可以理解为父亲的引用)。
this :代表当前对象的引用(谁调用就代表谁)。

子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。 super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。

继承的特点
1、Java中支持单继承
2、Java支持多层继承
3、子类和父类是一种相对的概念

Calendar类

java.lang.Object
继承者 java.util.Calendar
public abstract class Calendar
extends Object
implements Serializable, Cloneable, Comparable<Calendar>

java.util.Calendar日历类


在这里插入图片描述

public int get(int field):返回给定日历字段的值。
public void set(int field, int value):将给定的日历字段设置为给定值。
public abstract void add(int field, int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。
public Date getTime():返回一个表示此Calendar时间值(从历元到现在的毫秒偏移量)的Date对象。

System类

java.lang.System类中提供了大量的静态方法,可以获取与系统相关的信息或系统级操作,在System类的API文档中,常用的方法有:
public static long currentTimeMillis():返回以毫秒为单位的当前时间。
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):将数组中指定的数据拷贝到另一个数组中。

StringBuilder类

StringBuilder是个字符串的缓冲区,即它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。
public StringBuilder():构造一个空的StringBuilder容器。
public StringBuilder(String str):构造一个StringBuilder容器,并将字符串添加进去。

public StringBuilder append(...):添加任意类型数据的字符串形式,并返回当前对象自身。
public String toString():将当前StringBuilder对象转换为String对象。

一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

StringBuffer类

线程安全的可变字符序列。
一个类似于 String 的字符串缓冲区,但不能修改。

抽象类

我们把没有方法主体的方法称为抽象方法。
Java语法规定,包含抽象方法的类就是抽象类。
抽象方法 : 没有方法体的方法。
抽象类:包含抽象方法的类。
继承抽象类的子类必须重写父类所有的抽象方法
此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法。

  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
  2. 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
  3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象

接口

接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。

抽象方法:使用 abstract 关键字修饰,可以省略,没有方法体。该方法供子类实现使用。
默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。
静态方法:使用 static 修饰,供接口直接调用。
私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。

非抽象子类实现接口:

  1. 必须重写接口中所有抽象方法。
  2. 继承了接口的默认方法,即可以直接调用,也可以重写。
    抽象方法:
    子类必须全部实现
    默认方法:
    可以继承可以重写,但是只能通过实现类的对象来调用
    静态方法:
    静态和.class文件相关,只能使用接口名进行调用,不可以通过实现类的类名或者实现类的对象进行调用
    私有方法:
    只有默认方法可以调用
    私有静态方法:
    默认方法和静态方法可以调用
接口的多实现

接口中有多个抽象方法的时候,实现类必须重写所有的抽象方法,如果抽象方法存在重名,只需要重写一次
接口中,有多个默认方法时,实现类都可继承使用。如果默认方法有重名的,必须重写一次。
接口中,存在同名的静态方法并不会冲突,原因是只能通过各自接口名访问静态方法。

优先级的问题
当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法。

接口的多继承

一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用 extends 关键字,子接口继承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次。

子接口重写默认方法时,default关键字可以保留。子类重写默认方法时,default关键字不可以保留。

接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰。
接口中,没有构造方法,不能创建对象。
接口中,没有静态代码块。

多态

指同一行为,具有多个不同的表现形式
1、继承或者实现
2、方法的重写
3、父类应用指向子类对象
当使用多态调用方法的时候,首先检查父类中是否有该方法,如果没有,则编译错误,如果有执行的是子类重写后的方法

多态具有良好的扩展性:

应用类型转换

向上转型:
多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。当父类引用指向一个子类对象时,便是向上转型。
向下转型:
父类类型向子类类型向下转换的过程,这个过程是强制的。
一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。
多态带来的麻烦:
需要调用子类中的特有的方法必须使用向下转型
instanceof给引用变量做类型的校验,适用于在向下转型的时候先做一次判断,防止ClassCastException异常

final关键字

final: 不可改变。可以用于修饰类、方法和变量。
类:被修饰的类,不能被继承。
方法:被修饰的方法,不能被重写。
变量:被修饰的变量,不能被重新赋值。

修饰变量:
局部变量-基本类型:
基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改。
局部变量-引用类型:
引用类型的局部变量,被final修饰后,只能指向一个对象,地址不能再更改。但是不影响对象内部的成员变量值的修改

成员变量:

权限修饰符

public:公共的。
protected:受保护的
default:默认的
private:私有的

在这里插入图片描述

内部类

将一个类A定义在另一个类B中,里面那个类A就称为内部类,B称为外部类

成员内部类

定义在类中方法外的类

匿名内部类

是内部类的简化写法。它的本质是一个 带具体实现的 父类或者父接口的 匿名的 子类对象。
开发中,最常用到的内部类就是匿名内部类了。

包装类
在这里插入图片描述
装箱:从基本类型转换为对应的包装类对象。
拆箱:从包装类对象转换为对应的基本类型。
从Java 5(JDK 1.5)开始,基本类型与包装类的装箱、拆箱动作可以自动完成。

Collection集合

集合:集合是java中提供的一种容器,可以用来存储多个数据。
数组的长度是固定的。集合的长度是可变的。
数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。

Collection常用功能:
public boolean add(E e): 把给定的对象添加到当前集合中 。
public void clear() :清空集合中所有的元素。
public boolean remove(E e): 把给定的对象在当前集合中删除。
public boolean contains(E e): 判断当前集合中是否包含给定的对象。
public boolean isEmpty(): 判断当前集合是否为空。
public int size(): 返回集合中元素的个数。
public Object[] toArray(): 把集合中的元素,存储到数组中。

Iterator迭代器

迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。

public E next():返回迭代的下一个元素。
public boolean hasNext():如果仍有元素可以迭代,则返回 true。
tips::在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会发生java.util.NoSuchElementException没有集合元素的错误。

原理:
在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。

增强for循环

增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
仅仅作为遍历操作

可变参数

修饰符 返回值类型 方法名(参数类型... 形参名){ }
同样是代表数组,但是在调用这个带有可变参数的方法时,不用创建数组(这就是简单之处),直接将数组中的元素作为实际参数进行传递,其实编译成的class文件,将这些元素先封装到一个数组中,在进行传递。这些动作都在编译.class文件时,自动完成了。
不可变参数只能存在一个,且要卸载一个方法参数列表中的末尾

泛型

一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。
集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。
泛型是数据类型的一部分,我们将类名与泛型合并一起看做数据类型。

泛型E
自定义的泛型类
修饰符 class 类名<代表泛型的变量> { }
含有泛型的方法
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
含有泛型的接口
修饰符 interface接口名<代表泛型的变量> { }

泛型通配符
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

受限泛型
泛型的上限:
格式: 类型名称 <? extends 类 > 对象名称
意义: 只能接收该类型及其子类
泛型的下限:

格式: 类型名称 <? super 类 > 对象名称
意义: 只能接收该类型及其父类型

List集合

public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
public E get(int index) :返回集合中指定位置的元素。
public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

ArrayList集合
LinkdedList集合
public void addFirst(E e) :将指定元素插入此列表的开头。
public void addLast(E e) :将指定元素添加到此列表的结尾。
public E getFirst() :返回此列表的第一个元素。
public E getLast() :返回此列表的最后一个元素。
public E removeFirst() :移除并返回此列表的第一个元素。
public E removeLast() :移除并返回此列表的最后一个元素。
public E pop() :从此列表所表示的堆栈处弹出一个元素。
public void push(E e) :将元素推入此列表所表示的堆栈。
public boolean isEmpty() :如果列表不包含元素,则返回true。

Set接口

HashSet集合
哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的
LinkedHashSet集合

Collections类

java.util.Collections

public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。
public static void shuffle(List<?> list) 打乱顺序 :打乱集合顺序。
public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序。
public static <T> void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排序。

比较形式

Java提供两种比较形式:
java.lang.Comparable;
java.util.Comparator;

方法内部调用new Comparator()
两个对象比较的结果有三种:大于,等于,小于。
如果要按照升序排序, 则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数) 如果要按照降序排序 则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)
直接在函数中写匿名内部类

Map集合

public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。
public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。
public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。

public K getKey() :获取Entry对象中的键。
public V getValue() :获取Entry对象中的值。

HashMap集合

数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。

LinkedHashMap集合

ashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。

JDK9对集合添加的优化

使用与创建少量的元素:
1:.of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和子类实现并没有这类方法,比如HashSet,ArrayList等待;
2:返回的集合是不可变的;

上一篇下一篇

猜你喜欢

热点阅读