Java笔记3

接口 interface

1.有时必须从几个类中派生出一个子类,继承它们所有的属性和方法,但是Java不支持多重继承,有了接口,就可以得到多重继承的效果
2.接口是抽象方法和常量值的定义的集合
3.从本质上讲,接口是一种特殊的抽象类,这种抽象类只包含方法的定义和常量,而不包括方法的实现和变量。
4.实现接口类:
class Subclass implements InterfaceA{}
5.一个类可以实现多个接口,接口也可以继承其他接口

接口的特点
Ø 用interface来定义。
Ø 接口中的所有成员变量都默认是由public static final修饰的。
Ø 接口中的所有方法都默认是由public abstract修饰的。
Ø 接口没有构造器。
Ø 接口采用多层继承机制。

l 实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。
l 接口的主要用途就是被实现类实现。(面向接口编程)
l 与继承关系类似,接口与实现类之间存在多态性
l 定义Java类的语法格式:先写extends,后写implements
< modifier> class < name> [extends < superclass>] [implements < interface> [,< interface>]* ] {
< declarations>*
}
l 一个类可以实现多个无关的接口
interface Runner { public void run();}
interface Swimmer {public double swim();}
class Creator{public int eat(){…}}
class Man extends Creator implements Runner ,Swimmer{
public void run() {……}
public double swim() {……}
public int eat() {……}
}

l 与继承关系类似,接口与实现类之间存在多态性
public class Test{
public static void main(String args[]){
Test t = new Test();
Man m = new Man();
t.m1(m);
t.m2(m);
t.m3(m);
}
public String m1(Runner f) { f.run(); }
public void m2(Swimmer s) {s.swim();}
public void m3(Creator a) {a.eat();}
}

抽象类是对一类事物的高度抽象,其中既有属性,也有方法
而接口是对方法的抽象,也就是对一系列的动作抽象
所以,当对一类事物抽象的时候,使用抽象类
当对一系列的动作抽象的时候,使用接口。需要使用这些动作的类去实现相应的接口即可。

工厂方法(FactoryMethod)

FactoryMethod模式是设计模式中应用最为广泛的模式,在面向对象的编程中,对象的创建工作非常简单,对象的创建时机却很重要。FactoryMethod解决的就是这个问题,它通过面向对象的手法,将所要创建的具体对象的创建工作延迟到了子类,从而提供了一种扩展的策略,较好的解决了这种紧耦合的关系。

类的成员之五:内部类

l 在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。
l Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。
Ø Inner class的名字不能与包含它的类名相同;
l Inner class可以使用外部类的私有数据,因为它是外部类的成员,同一个类的成员之间可相互访问。而外部类要访问内部类中的成员需要:内部类.成员或者内部类对象.成员。
l 分类:成员内部类(static成员内部类和非static成员内部类)
局部内部类(不谈修饰符)、匿名内部类
public class Test{
int I;
private int j;
Class A{
int i ;//内部类的属性
public void setTestFileds(){
Test.this.i = 1;
Test.this.j = 2;
}
public viod set(){
this.i = 10;
}
}
public void setInfo(){
new A().setTestFilesd();//外部类要调用内部的方法,需要 new对象
}

内部类特性

l Inner class作为类的成员:
Ø 可以声明为final的
Ø 和外部类不同,Inner class可声明为private或protected;
Ø Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;
Ø Inner class作为类:
可以声明为abstract类 ,因此可以被其它的内部类继承
【注意】非static的内部类中的成员不能声明为static的,只有在外部类或static的内部类中才可声明static成员。

内部类的作用?-----------内部类主要是为了解决Java不能多重继承的问题

异常处理

java.lang.ArrayIndexOutOfBoundsException 数组越界异常
java.lang.NullPointerException 空指针异常
java.lang.ArithmeticException 错误运算 (by 0 )

 常见异常
 RuntimeException
• 错误的类型转换
• 数组下标越界
• 空指针访问
 IOExeption
• 从一个不存在的文件中读取数据
• 越过文件结尾继续读取EOFException
• 连接一个不存在的URL

异常处理机制

 Java提供的是异常处理的抓抛模型。
 Java程序的执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。
 如果一个方法内抛出异常,该异常会被抛到调用方法中。如果异常没有在调用方法中处理,它继续被抛给这个调用方法的调用者。这个过程将一直继续下去,直到异常被处理。这一过程称为捕获(catch)异常。
 如果一个异常回到main()方法,并且main()也不处理,则程序运行终止。
 程序员通常只能处理Exception,而对Error无能为力。

异常处理是通过try-catch-finally语句实现的。
try catch 是为了防止程序可能出现的异常
在捕获异常的代码块中,如果前面的代码有异常了,就不会执行后面的。
try
{
… //可能产生异常的代码
}
catch( ExceptionName1 e )
{
… //当产生ExceptionName1型异常时的处置措施
}
catch( ExceptionName2 e )
{
… //当产生ExceptionName2型异常时的处置措施
}
[ finally{ //finally可以写也可以不写
… //无条件执行的语句
} ]

 捕获异常的有关信息
与其它对象一样,可以访问一个异常对象的成员变量或调用它的方法。
• getMessage( ) 方法,用来得到有关异常事件的信息
• printStackTrace( )用来跟踪异常事件发生时执行堆栈的内容。

声明抛出异常
 声明抛出异常是Java中处理异常的第二种方式
• 如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显式地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
• 在方法声明中用 throws 子句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。
 声明抛出异常举例:
public void readFile(String file) throws FileNotFoundException {
……
// 读文件的操作可能产生FileNotFoundException类型的异常
FileInputStream fis = new FileInputStream(file);
………
}

可以在main方法抛出异常,但是就直接抛到Java虚拟机上了,便无法处理了。

重写方法声明抛出异常的原则
• 重写方法不能抛出比被重写方法范围更大的异常类型。即子类不能抛出比父类范围更大的异常类型。(NullPointerException 的父类是 Exception)

人工抛出异常
 Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要人工创建并抛出

创建用户自定义异常类
Java提供的异常的类是够用的,只有特殊的需要自己编写异常类
用户自定义异常类MyException,用于描述数据取值范围错误信息。用户自己的异常类必须继承现有的异常类。

Java集合概述

Java集合类存放于 java.util 包中,是一个用来存放对象的容器。
• ①、集合只能存放对象。比如你存一个 int 型数据 1放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。
• ②、集合存放的是多个对象的引用,对象本身还是放在堆内存中。
• ③、集合可以存放不同类型,不限数量的数据类型。

Java 集合可分为 Set、List 和 Map 三种大体系
Set:无序、不可重复的集合
List:有序,可重复的集合
Map:具有映射关系的集合
在 JDK5 之后,增加了泛型,Java 集合可以记住容器中对象的数据类型

HashSet

HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。我们大多数时候说的set集合指的都是HashSet
HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取和查找性能。
HashSet 具有以下特点:
不能保证元素的排列顺序
不可重复
HashSet 不是线程安全的
集合元素可以存 null
当向HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。
如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

add添加元素
remove移除元素
contain是否包含元素
clear清空集合

如何让遍历集合?
1.使用迭代器遍历集合 Iterator
Iterator it = set. Iterator();
while(it.hasNext()){
syso(it.hasNext());
}

2.用for each迭代集合 (推荐使用)
for(object obj : set){ //把set的每一个值取出来,赋值给obj,直到循环set的所有值
syso(obj);
}
syso(set.size()); //获取集合中元素的个数

hashCode() 方法

HashSet 集合判断两个元素相等的标准:两个对象通过 equals() 方法比较相等,并且两个对象的 hashCode() 方法返回值也相等。

如果想要让集合只存同样类型的对象,则使用***泛型***
Set set1 = new HashSet(); //比如指定String为集合的泛型
set1.add(“sbc”);

TreeSet

TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。
TreeSet 支持两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。

自然排序
排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序排列
• 如果 this > obj,返回正数 1
• 如果 this < obj,返回负数 -1
• 如果 this = obj,返回 0 ,则认为这两个对象相等
• 必须放入同样类的对象.(默认会进行排序) 否则可能会发生类型转换异常.我们可以使用泛型来进行限制

定制排序
如果需要实现定制排序,则需要在创建 TreeSet 集合对象时,提供一个 Comparator 接口的实现类对象。由该 Comparator 对象负责集合元素的排序逻辑

List与ArrayList

List 代表一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引。
List 允许使用重复元素,可以通过索引来访问指定位置的集合元素。
List 默认按元素的添加顺序设置元素的索引。
List 集合里添加了一些根据索引来操作集合元素的方法

ArrayList 和 Vector

ArrayList 和 Vector 是 List 接口的两个典型实现
区别:
• Vector是一个古老的集合,通常建议使用 ArrayList
• ArrayList 是线程不安全的,而 Vector 是线程安全的。
• 即使为保证 List 集合线程安全,也不推荐使用 Vector

Map

Map 用于保存具有映射关系的数据,因此 Map 集合里保存着两组值,一组值用于保存 Map 里的 Key,另外一组用于保存 Map 里的 Value
Map 中的 key 和 value 都可以是任何引用类型的数据
Map 中的 Key 不允许重复,即同一个 Map 对象的任何两个 Key 通过 equals 方法比较中返回 false
Key 和 Value 之间存在单向一对一关系,即通过指定的 Key 总能找到唯一的,确定的 Value。

HashMap & Hashtable

HashMap 和 Hashtable 是 Map 接口的两个典型实现类
区别:
• Hashtable 是一个古老的 Map 实现类,不建议使用
• Hashtable 是一个线程安全的 Map 实现,但 HashMap 是线程不安全的。
• Hashtable 不允许使用 null 作为 key 和 value,而 HashMap 可以。
与 HashSet 集合不能保证元素的顺序一样,Hashtable 、HashMap 也不能保证其中 key-value 对的顺序
Hashtable 、HashMap 判断两个 Key 相等的标准是:两个 Key 通过 equals 方法返回 true,hashCode 值也相等。
Hashtable 、相等的标准是:两个 Value 通过 equalHashMap 判断两个 Values 方法返回 true

TreeMap

TreeMap 存储 Key-Value 对时,需要根据 Key 对 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态。
TreeMap 的 Key 的排序:
自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的Key 应该是同一个类的对象,否则将会抛出 ClasssCastException
定制排序(了解):创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口

操作集合的工具类:Collections

Collections 是一个操作 Set、List 和 Map 等集合的工具类
Collections 中提供了大量方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法
排序操作:
• reverse(List):反转 List 中元素的顺序
• shuffle(List):对 List 集合元素进行随机排序
• sort(List):根据元素的自然顺序对指定 List 集合元素按序排序
• sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
• swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换

查找、替换

Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
Object min(Collection)
Object min(Collection,Comparator)
int frequency(Collection,Object):返回指定集合中指定元素的出现次数
boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值

同步控制

Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题

泛型 Generic

一、 为什么要有泛型Generic?
泛型,JDK1.5新加入的,解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可。
Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮。

• Java中的***泛型,只在编译阶段有效***。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦除,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。

泛型的使用
1.泛型类
2.泛型方法
3.泛型接口

3.1 泛型类
1.对象实例化时不指定泛型,默认为:Object。
2.泛型不同的引用不能相互赋值

3.2 泛型接口
//定义一个泛型接口
interface Generator {
T next();
}
/**

  • 未传入泛型实参时与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
  • 即:class FruitGenerator implements Generator{
  • 如果不声明泛型,如:class FruitGenerator implements Generator,编译器会报错:“Unknown class”
    */
    class FruitGenerator implements Generator{
    @Override
    public T next() {
    return null;
    }
    }

/**

  • 传入泛型实参时
  • 定义一个生产器实现这个接口,虽然我们只创建了一个泛型接口Generator
  • 但是我们可以为T传入无数个实参,形成无数种类型的Generator接口。
  • 在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型
  • 即:Generator,public T next();中的的T都要替换成传入的String类型。
    */
    class FruitGenerator implements Generator {
    @Override
    public String next() {
    // TODO Auto-generated method stub
    return null;
    }
    }

3.3 泛型方法
方法,也可以被泛型化,不管此时定义在其中的类是不是泛型化的。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。
泛型方法的格式:
public class DAO {
public void show(E e){
System.out.println(e.toString());
}
public T show1(T t){
return t;
}
}

/**

  • 泛型方法与可变参数
  • @param args
    */
    public void printMsg( T… args){
    for(T t : args){
    System.out.println("泛型测试 ,t is " + t);
    }
    }

/**

  • 静态方法无法访问类上定义的泛型;
  • 如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上
  • @author lby
  • @param
    /
    class StaticGenerator {
    /
    *
    • 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法)
    • 即使静态方法要使用泛型类中已经声明过的泛型也不可以。
    • 如:public static void show(T t){…},此时编译器会提示错误信息:
      “StaticGenerator cannot be refrenced from static context”
      */
      public static void show(T t){
      }
      }
3.4 通配符

/**

  • 不确定集合中的元素具体的数据类型
  • 使用?表示所有类型
  • @param list
    */
    public void test(List<?> list){
    System.out.println(list);
    }

3.5.1 有限制的通配符

举例:

<? extends Person> (无穷小 , Person] 只允许泛型为Person及Person子类的引用调用 <? super Person > [Person , 无穷大) 只允许泛型为Person及Person父类的引用调用 <? extends Comparable> 只允许泛型为实现Comparable接口的实现类的引用调用 ## 枚举类 enum 在某些情况下,一个类的对象是有限而且固定的。例如季节类,只能有 4 个对象 手动实现枚举类: • private 修饰构造器 • 属性使用 private final 修饰 • 把该类的所有实例都使用 public static final 来修饰 使用 enum 定义枚举类 • JDK 1.5 新增的 enum 关键字用于定义枚举类 • 枚举类和普通类的区别: • 使用 enum 定义的枚举类默认继承了 java.lang.Enum 类 • **枚举类的构造器只能使用 private 访问控制符** • **枚举类的所有实例必须在枚举类中显式列出(, 分隔 ; 结尾). 列出的实例系统会自动添加 *public static final* 修饰** • 所有的枚举类都提供了一个 values 方法, 该方法可以很方便地遍历所有的枚举值 • JDK 1.5 中可以在 switch 表达式中使用枚举类的对象作为表达式, case 子句可以直接使用枚举值的名字, 无需添加枚举类作为限定 • 若枚举只有一个成员, 则可以作为一种单子模式的实现方式 枚举类的属性 • 枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰 • 枚举类使用 private final 修饰的属性应该在构造器中为其赋值 • 若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数 **实现接口的枚举类** • 和普通 Java 类一样枚举类可以实现一个或多个接口 • 若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式, 则可以让每个枚举值分别来实现该方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值