当前位置: 首页 > news >正文

哪里的网站可以做围棋死活题专做宝宝辅食的网站

哪里的网站可以做围棋死活题,专做宝宝辅食的网站,wordpress 禁止目录浏览,wordpress 头条主题一、抽象类 当编写一个类时#xff0c;我们往往会为该类定义一些方法#xff0c;这些方法是用来描述该类的行为方式#xff0c;那么这些方法都有具体的方法体。 分析事物时#xff0c;发现了共性内容#xff0c;就出现向上抽取。会有这样一种特殊情况#xff0c;就是功…一、抽象类 当编写一个类时我们往往会为该类定义一些方法这些方法是用来描述该类的行为方式那么这些方法都有具体的方法体。 分析事物时发现了共性内容就出现向上抽取。会有这样一种特殊情况就是功能声明相同但功能主体不同。那么这时也可以抽取但只抽取方法声明不抽取方法主体。那么此方法就是一个抽象方法 通过java中的关键字abstract(抽象)。 当定义了抽象函数的类也必须被abstract关键字修饰被abstract关键字修饰的类是抽象类。 例如 abstract class 犬科 {abstract void 吼叫();//抽象函数。需要abstract修饰并分号;结束 } class Dog extends 犬科 {void 吼叫(){System.out.println(汪汪汪汪);} } class Wolf extends 犬科{void 吼叫(){System.out.println(嗷嗷嗷嗷);} } 抽象类的特点 1、抽象类和抽象方法都需要被abstract修饰。抽象方法一定要定义在抽象类中。 2、抽象类不可以创建实例原因调用抽象方法没有意义。 3、只有覆盖了抽象类中所有的抽象方法后其子类才可以实例化。否则该子类还是一个抽象类。 细节问题 1、抽象类一定是个父类 是的因为不断抽取而来的。2、抽象类是否有构造函数 有虽然不能给自己的对象初始化但是可以给自己的子类对象初始化。抽象类和一般类的异同点相同1、它们都是用来描述事物的。2、它们之中都可以定义属性和行为。不同1、一般类可以具体的描述事物。抽象类描述事物的信息不具体2、抽象类中可以多定义一个成员抽象函数。3、一般类可以创建对象而抽象类一定不能创建对象。3、抽象类中是否可以不定义抽象方法。 是可以的4、抽象关键字abstract不可以和哪些关键字共存 1、finalfianl修饰的类是无法被继承的而abstract修饰的类一定要有子类。 final修饰的方法无法被覆盖但是abstract修饰的方法必须要被子类去实现的。 2、static静态修饰的方法属于类的它存在与静态区中和对象就没关系了。而抽象方法没有方法体使用类名调用它没有任何意义。 3、private私有的方法子类是无法继承到的也不存在覆盖而abstract和private一起使用修饰方法abstract既要子类去实现这个方法而private修饰子类根本无法得到父类这个方法。互相矛盾。 二、接口 当一个抽象类中的所有方法都是抽象方法时那么这个抽象类就可以使用另外一种接口这种机制来体现。 接口怎么定义呢定义普通的类或者抽象类可以使用class关键字定义接口必须interface关键字完成。 interface class Demo{abstract void show1();abstract void show2(); } 接口中只能定义常量 1、 接口成员的特点 1、接口中可以定义变量但是变量必须有固定的修饰符修饰public static final 所以接口中的变量也称之为常量。 2、接口中可以定义方法方法也有固定的修饰符public abstract现在可以没有 3、接口中的成员都是公共的。 4、接口不可以创建对象。 5、子类必须覆盖掉接口中所有的抽象方法后子类才可以实例化否则子类是一个抽象类。 2、接口-多实现 接口最重要的体现解决多继承的弊端将多继承这种机制在java中通过多实现完成了。 interface A{void abstract show1(); } interface B{void abstract show2(); } // 多实现。同时实现多个接口。 class C implements A,B{public void show1(){}public void show2(){} } 怎么解决多继承的弊端呢 弊端多继承时当多个父类中有相同功能时子类调用会产生不确定性。 其实核心原因就是在于多继承父类中功能有主体而导致调用运行时不确定运行哪个主体内容。 而在多实现里 因为接口中的功能都没有方法体由子类来明确来源确定就是实现他们的实现类。 3、接口的多继承 多个接口之间可以使用extends进行继承。 interface A{abstract void show(); } interface B{abstract void show1(); } interface C{abstract void show2(); } interface D extends A,B,C{abstract void show3(); } 总结接口在开发中的它好处 1、接口的出现扩展了功能。 2、接口其实就是暴露出来的规则。 3、接口的出现降低了耦合性即设备与设备之间实现了解耦。 接口和抽象的区别 相同点: 都位于继承的顶端,用于被其他实现或继承;都不能实例化;都包含抽象方法,其子类都必须覆写这些抽象方法; 区别: 抽象类为部分方法提供实现,避免子类重复实现这些方法,提供代码重用性;接口只能包含抽象方法极度的抽象类;一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承) 二者的选用: 优先选用接口,尽量少用抽象类;需要定义子类的行为,又要为子类提供共性功能时才选用抽象类; 三、集合 1、集合与数组 集合和数组的容器 数组的长度是固定的集合的长度是可变的。 数组中存储的是同一类型的元素可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一致。 集合作用当对象多的时候先进行存储。 2、集合框架的由来 集合本身是一个工具它存放在java.util包中。 不同的容器进行不断的向上抽取最后形成了一个集合框架这个框架就是Collection接口。在Collection接口定义着集合框架中最共性的内容。 在学习时我们需要看最顶层怎么用 创建底层对象即可。因为底层继承了父类中的所有功能 3、Collection接口 Collection接口是集合中的顶层接口它中定义的所有功能子类都可以使用。。一些 collection 允许有重复的元素而另一些则不允许。一些 collection 是有序的而另一些则是无序的。 可以使用多态 3.1、Collection基本方法了解 Collection coll new ArrayList(); //1,往集合中添加对象元素。add(Object); coll.add(itcast1); coll.add(itcast2); coll.add(itcast3); //2,删除。 coll.remove(itcast2); //3,判断是否包含。 System.out.println(coll.contains(itcast11)); //4,清除。 coll.clear(); //把集合打印一下。 System.out.println(coll);//[itcast1, itcast2, itcast3] 3.2、集合的使用 在使用集合时需要注意: 集合中存储其实都是对象的地址。集合中可以存储基本数值吗不行但是jdk1.5以后可以这么写但是存储的还是对象(基本数据类型包装类对象)。存储时提升了Object。取出时要使用元素的特有内容必须向下转型(一般在迭代中体现)。 Collection coll new ArrayList();coll.add(abc); coll.add(aabbcc); coll.add(shitcast);for (Iterator it coll.iterator(); it.hasNext();) {//由于元素被存放进集合后全部被提升为Object类型当需要使用子类对象特有方法时需要向下转型String str (String) it.next();System.out.println(str.length()); } 3.3、集合中存放自定义对象 //创建一个自定义类 public class Student {private String name;private int age;public Student(String name, int age) {super();this.name name;this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}pulic void setAge(int age) {this.age age;}Overridepublic String toString() {return Student [name name , age age ];}//建立学生的自己比较方式public boolean equals(Object o){if(this o){return true;}if((o instanceof Student)!){throw new ClassCastException();}Student s (Student)o;return this.age s.age this.name.equals(s.name);} } //创建集合对象存储自定义对象。 class CollectionDemo {public static void main(String[] args){Collection coll new ArrayList();Student s new Student(zhangsan,21);coll.add(s);coll.add(new Student(lisi,22));coll.add(new Student(wangwu,23));for(Iterator it coll.iterator();it.hasNaxt();){Student s (Student)it.next();Sysem.out.println(s);}} }在给集合中存放对象时集合中的所有对象有自己的方法比较是不是同一元素。一般情况都是使用equals方法而Object中的equals方法是比较的是两个对象的内存地址是否相同而在开发的时候我们需要根据对象的自身数据建立属于对象特有的比较方法这时我们需要复写equals方法。 四、集合-List 1、 List接口介绍 List集合是有序的 collection也称为序列此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引在列表中的位置访问元素并搜索列表中的元素。 与 set 不同list列表通常允许重复的元素。 总结: List:有序的带索引的通过索引就可以精确的操作集合中的元素元素是可以重复的。 2、List接口方法 List提供了增删改查动作 增加add(element); add(index,element);删除remove(element); remove(index);修改set(index,element);查询get(index); List list new ArrayList(); //1,添加元素。 list.add(new Student(wangcai1,21)); list.add(new Student(wangcai2,22)); list.add(new Student(wangcai3,23));//2,插入元素。 list.add(1, new Student(xiaoqiang,25)); //3,删除元素。 list.remove(2);//IndexOutOfBoundsException//4,修改元素。 list.set(1, new Student(xiaoming,11));for (Iterator it list.iterator(); it.hasNext();) {Student stu (Student) it.next();System.out.println(stu); }//和数组一样角标从0开始 由于List集合拥有索引因此List集合迭代方式除了使用迭代器之外还可以使用索引进行迭代。 for (int i 0; i list.size(); i) {Student stu (Student) list.get(i);System.out.println(stu); } 3、ListIterator接口 在迭代过程中如果我们使用了集合的方法对元素进行操作。就会导致迭代器并不知道集合中的变化容易引发数据的不确定性。发生异常java.util.ConcurrentModificationException 解决方法 在迭代时不要使用集合的方法操作元素。使用迭代器的方法操作。但是迭代器Iterator的方式只有 hasNext() ,next(),remove();Iterator有一个子接口ListIterator可以完成该问题的解决。通过List接口中的listIterator()就可以获取。 //创建List容器List list new ArrayList();//给容器中添加元素list.add(abc1);list.add(abc2);list.add(abc3);list.add(abc4);//遍历容器当有元素为abc2时添加一个itcastListIterator it list.listIterator();while(it.hasNext()){Object obj it.next();if(abc2.equals(obj)){it.add(itcast);}} 注意该列表迭代器只有List接口有。而且这个迭代器可以完成在迭代过程中的增删改查动作。 4、List常用子类介绍 首先我们来学习List下的常用集合ArrayList、Vector、LinkedList集合。 ArrayList是数组结构长度是可变的原理是创建新数组复制数组查询速度很快增删较慢不同步的。 Vector可以增长的数组结构。同步的。效率非常低。已被ArrayList替代。 LinkedList是链表结构不同步的增删速度很快查询速度较慢。 ArrayList和LinkedList详细介绍可见我的另一篇博客最详细的ArrayList和LinkedList区别及底层原理 五、集合-Set 1、Set介绍 List中是可以存放重复元素的。Collection接口中的另一个Set集合中的元素就是不重复的。 Set不包含重复元素的集合不保证顺序。而且方法和Collection一致。Set集合取出元素的方式只有一种迭代器。 Set集合有多个子类这里我们介绍其中的HashSet、TreeSet和LinkedHashSet这三个集合。 HashSet哈希表结构不同步保证元素唯一性的方式依赖于hashCode(),equals()方法。查询速度快。 哈希表 哈希表底层使用的也是数组机制数组中也存放对象而这些对象往数组中存放时的位置比较特殊当需要把这些对象给数组中存放时那么会根据这些对象的特有数据结合相应的算法算法这个对象在数组中的位置然后把这个对象存放在数组中。而这样的数组就称为哈希数组即就是哈希表。 当给哈希表中存放元素时需要根据元素的特有数据结合相应的算法这个算法其实就是Object中的hashCode方法既然Object的方法那么大家都能用。 注意如果两个对象hashCode方法算出结果一样这样现象称为哈希冲突这时会调用对象的equals方法比较这两个对象是不是同一个对象如果equals方法返回的是true那么就不会把第二个对象存放在哈希表中如果返回的是false就会把这个值存放在哈希表中去重。 总结 去重就是根据对象的hashCode和equals方法来决定的 2、HashSet 给HashSet中存放自定义对象时需要复写对象中的hashCode和equals方法建立自己的比较方式才能保证HashSet集合中的对象唯一。 // 创建自定义对象Student public class Student {private String name;private int age;public Student(String name, int age) {super();this.name name;this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}Overridepublic String toString() {return Student [name name , age age ];}Overridepublic int hashCode(){final int prime 31;int result 1;result prime*result age;result prime*result (name null)? 0 : name.hashCode());return result;}Overridepublic boolean equals(Object o){if(this o){return true;}if(!(o instanceof Student)){throw new ClassCastException(错误);}Student s (Student)o;return this.age s.age this.name.equals(s.name);} } class HashSetDemo {public static void main(String[] args) {//创建HashSet对象HashSet hs new HashSet();//给集合中添加自定义对象hs.add(new Student(zhangsan,21));hs.add(new Student(lisi,22));hs.add(new Student(wangwu,23));hs.add(new Student(zhangsan,21));//取出集合中的每个元素Iterator it hs.iterator();while(it.hasNext()){Student s (Student)it.next();System.out.println(s);}} } 3、LinkedHashSet 我们知道HashSet保证元素唯一并且查询速度很快可是元素存放进去是没有顺序的那么我们要保证有序还要速度快在HashSet下面有一个子类LinkedHashSet它是链表和哈希表组合的一个数据存储结构。 public class LinkedHashSetDemo {public static void main(String[] args) {Set set new LinkedHashSet();set.add(bbb);set.add(aaa);set.add(abc);set.add(bbc);//放入有顺序取出有顺序for (Iterator it set.iterator(); it.hasNext();) {System.out.println(it.next());}} } 4、TreeSet TreeSet集合是可以给对象进行排序的。当存放进去的对象会根据对象的自身的特点进行自然顺序的排序。因此这里需要注意的当我们给TreeSet集合中存放自定义对象时一定要保证对象自身具备比较功能如何才能让对象自身具备比较功能呢 当需要一个对象自身具备功能时只需要这个对象实现Comparable接口并实现其中的compareTo方法即可。 public class Student implements Comparable{private String name;private int age;public Student(String name, int age) {super();this.name name;this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}Overridepublic String toString() {return Student [name name , age age ];}/** 重写compareTo方法建立学生的自然排序(对象的默认排序方式)。按照学生年龄排序。*/Overridepublic int compareTo(Object o){if((o instanceof Student)){thorw new ClassCastException();}Student s (Student)o;int temp this.age - s.age;return temp 0 ? this.name.compareTo(s.name) : temp;} } public class TreeSetDemo {public static void main(String[] args) {//创建TreeSet对象TreeSet ts new TreeSet();//给集合中添加自定义对象ts.add(new Student(zhangsan,21));ts.add(new Student(lisi,22));ts.add(new Student(wangwu,23));ts.add(new Student(zhangsan,21));ts.add(new Student(zhaoliu,21));//取出集合中的每个元素Iterator it ts.iterator();while(it.hasNext()){Student s (Student)it.next();System.out.println(s);}} } 总结: TreeSet:可以对Set集合中的元素进行排序。元素自身具备自然排序其实就是实现了Comparable接口重写了compareTo方法。 如果元素自身不具备自然排序或者具备的自然排序不是所需要的这时怎么办呢 继续查看TreeSet集合说明发现还有一个叫做Comparator的接口并且TreeSet集合的接口允许我们给其传递这样一个接口的子类对象。 其实就是在创建TreeSet集合时在构造函数中指定具体的比较方式。需要定义一个类实现Comparator接口重写compare方法。 到此为止再往集合中存储对象时通常该对象都需要覆盖hashCodeequals同时实现Comparale接口建立对象的自然排序。通常还有一个方法也会复写toString(); 六、集合-Map 1、介绍 在学习数组时我们说如果和数组角标有一定的对应关系是可以把数据存放在数组中通过数组的角标来获取对应的数据把这种方式称为查表法。 可是当我们的对象与对象之间有了对应的关系我们需要把这样具有对应关系的一对数据存放起来怎么做呢采用数组只能存放具有简单对应关系的数据不太合适。采用Collection集合可是只能存放一个对象无法维护这种关系。怎么做呢 Java中我们提供了相应的其他容器来解决这个容器就是Map集合。将键映射到值的对象。一个映射不能包含重复的键每个键最多只能映射到一个值。 例 public class MapDemo {public static void main(String[] args){//创建Map对象MapString,String map new HashMapString,String();//给map中添加元素map.put(星期一, Monday);map.put(星期日, Sunday);//当给Map中添加元素会返回key对应的原来的value值若key没有对象的值返回nullSystem.out.println(map.put(星期一, M)); /根据指定的key获取对应的valueString en map.get(星期日);System.out.println(en);//根据key删除元素,会返回key对应的value值String value map.remove(星期日);System.out.println(value);} } 2、Map集合中的方法 2.1、keySet方法 由于Map中的所有key都是不重复的所以获取到Map中的所有key应该会存放在Set集合中这个方法叫keySet public class MapDemo {public static void main(String[] args){// 创建集合MapString,String map new HsahMapString,String();// 添加元素map.put(星期一,Monday);map.put(星期日, Stringunday);//获取Map中的所有keySetString set map.keySet();//遍历存放所有key的Set集合IteratorString it keySet.iterator();while(it.hasNext()){String key it.next();String value map.get(key);System.out.println(keyvalue);}} }2.2、entrySet方法 这个方法的描述是得到所有key和value的映射关系这是啥意思呢假设Map中存放一对一对的夫妻那么entrySet获取到是每一对夫妻这种夫妻关系。 public class MapDemo {public static void main(String[] args) {//创建Map对象MapString, String map new HashMapString,String();//给map中添加元素map.put(星期一, Monday);map.put(星期日, Sunday);//获取Map中的所有key与value的对应关系SetEntryString,string entry map.entrySet();//遍历集合IteratorEntryString,String it entry.iterator();while(it.hasNext()){//得到每一对对应关系EntryString,String entry it.next();//通过每一对对应关系获取对应的keyString key entry.getKey();//通过每一对对应关系获取对应的valueString value entry.getValue();System.out.println(keyvalue);注意Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。 3、Map常用子类介绍 Map有多个子类这里我们主要讲解常用的HashMap和TreeMap集合; HashMap数据结构-哈希表。不是同步的允许null作为键和值。HashMap下有个子类LinkedHashMap基于链表哈希表。可以保证map集合有序存入和取出的顺序一致。 TreeMap数据结构-二叉树。不是同步的。可以对map集合中的键进行排序。 3.1、HashMap 练习学生对象(姓名年龄)都有自己的归属地 public class HashMapTest {public static void main(String[] args) {//1,创建hashmap集合对象。MapStudent,String map new HashMapStudent,String();//2,添加元素。map.put(new Student(lisi,28), 上海);map.put(new Student(wangwu,22), 北京);map.put(new Student(zhaoliu,24), 成都);map.put(new Student(zhouqi,25), 广州);map.put(new Student(wangwu,22), 南京);//3,取出元素。keySet entrySet//SetStudent keySet map.keySet();//for(Student key : keySet){}for(Student key : map.keySet()){String value map.get(key);System.out.println(key.toString().....value);}注意当给HashMap中存放自定义对象时如果自定义对象作为key存在这时要保证对象唯一必须复写对象的hashCode和equals方法 HashMap的详细深入了解请见我的另一篇博客HashMap大家族 3.2、TreeMap 练习按照学生的年龄进行从小到大的排序。 TreeMap。 public class TreeMapTest {public static void main(String[] args) {// 1,创建TreeMap集合对象。MapStudent, String map new TreeMapStudent, String();// 2,添加元素。map.put(new Student(lisi, 28), 上海);map.put(new Student(wangwu, 22), 北京);map.put(new Student(zhaoliu, 24), 成都);map.put(new Student(zhouqi, 25), 广州);map.put(new Student(wangwu, 22), 南京);//3,取出所有元素entrySet()for(Map.EntryStudent,String me : map.entrySet()){Student key me.getkey();String value me.getvalue();System.out.println(key::value);}给TreeMap存放自定义对象自定义对象作为key进行排序时自定义对象必须具备比较功能即实现Comparable接口。如果需要特定方式进行比较我们也可以给TreeMap集合传递自定义的比较器进行比较。 4、Map练习-字母出现次数 获取字符串中每一个字母出现的次数。要求返回结果个格式是 a(1)b(2)d(4)…; public class Maptext{public static void main(String[] args) {String str awaaacrebarct,btydui[efgkiryuiop;str getCharCount(str);System.out.println(str);}//获取字符串中的字母出现次数。public static String getCharCount(String str){//1.字符串转数组char[] chs str.toCharArray();//2.定义表TreeMapCharacter,Integer map new TreeMapCharacter,Integer();//3.遍历字符数组for(int i 0;ichs.length;i){if(!(chs[i] a chs[i]z || chs[i]A chs[i]Z)){continue;}//4将遍历到的字母作为键去查map这个表。获取对应的次数。Integer value map.get(chs[i]);//5有可能要查询的字母在表中不存在对应的次数需要判断。//如果返回是null说明字母没有对应的次数。就将这个字母和1存储到表中。if(value null){//将字母和1存储。map.put(chs[i],1);}else{value;map.put(chs[i],value);}}return mapToString(map);}/** 将map集合中的键值转成 格式是 a(1)b(2)d(4)......* map中有很多数据无论是多少个什么类型最终都变成字符串。* StringBuffer 这个容器就符合这个需求。如果是单线程建议使用StringBuilder。* */private static String mapToString(MapCharacter,Integer map){//1明确容器。StringBuilder sb new StringBuilder();//2.遍历map集合for(Character key : map.keySet()){Integer value map.get(key);sb.append(key(value));}return sb.toString();} } 七、泛型 1、泛型概述 1.1、什么是泛型 在以前集合中是可以存放任意对象的只要把对象丢尽集合后那么这时他们都会被提升成Object类型。当我们在取出每一个对象并且进行相应的操作这时必须采用类型转换。 但是由于集合中什么类型的元素都可以存储。导致取出时如果出现强转就会引发运行时 ClassCastException。怎么来解决这个问题呢 幸好JDK1.5以后出现了解决方案使用容器时必须明确容器中元素的类型。这种机制称之为 泛型。 1.2、泛型格式 对象类名称 数据类型 这种格式不是很难理解尖括号也是括号往括号里面写东西其实就是在传递参数。 1.3、泛型的特点 1安全机制。 2将运行时期的ClassCastException转移到了编译时期变成了编译失败。 3泛型技术是给编译器使用的技术。 4避免了强转的麻烦。 2、泛型的使用 2.1、简单使用 要求定义容器要求容器中元素唯一并且按指定的方法排序。 思路 1、元素唯一那么只能使用Set集合 2、还要对元素排序那么就使用TreeSet集合 3、还要按照指定方式排序那么就要让集合自定具备比较功能即就是要让要给集合传递一个比较器。 public class GenericDemo {public static void main(String[] args) {//  定义容器要求容器中元素唯一并且按指定的方法排序。并且使用匿名内部类的形式来完成比较器传递TreeSetString set new TreeSetString(new ComparatorString(){Overridepublic int compare(String o1, String o2) {int temp o1.length() - o2.length();return temp 0 ? o1.compareTo(o2):temp;}});set.add(abc);set.add(bbb);set.add(sh);set.add(itcast);for (String str : set) {System.out.println(str);}} } 2.2、泛型类 小知识泛型基本有了个了解之后在这里要给大家说下泛型这种技术是编译时期的技术也就是说在编译的时候编译会根据所写泛型进行类型的检查当编译通过后生成的class文件中是没有泛型这个机制的这种机制也称为泛型的擦除。这个小知识作为了解。 为了避免向下转型带来的异常发生风险我们使用泛型类来解决这个问题。 class ToolT{private T obj;public T getObj() {return obj;}public void setObj(T obj) {this.obj obj;} } public class GenericDemo2 {public static void main(String[] args) {ToolString t new ToolString();String s t.setobj();System.out.println(s);} 2.3、泛型方法 若是把泛型都定义在类上了也就是说在创建类的对象时候需要明确具体的类型但是这个局限性很大这时我们可以把泛型定义方法上这样的方法就称为泛型方法。 class UtilsW{//打印功能的方法可以打印任意类型,把泛型定义方法上public T void print(T t){System.out.println(t);}//也可以使用类上的泛型public void methed(W w){System.out.println(w);}//如果方法是静态那么方法上是无法使用类上的泛型因为类上的泛型是随着对象的创建才明确出来的public static Q q void show(Q q){System.out.println(show..q);} }2.4、泛型接口 定义在接口中的泛型再使用的时候: 1.子类已经明确具体的类型那么子类在实现的时候就把类型明确出来。 2.子类不明确具体类型需要子类创建对象时才能明确这时在子类描述时可以在子类上继续加泛型。 interface InterE{void show(); } //子类明确具体类型 class InterImpl1 implements InterString{public void show(){System.out.println(show run);} } //如果子类不明确具体数据类型这时可以在子类上继续使用泛型 class InterImpl2T implements InterT{public void show(){System.out.println(show run);} } public class GenericDemo2 {public static void main(String[] args) {new InterImpl().show();new InterImpl2String().show(); } 3、泛型通配符及限定 3.1、泛型通配符 示例 public class Solution {public static void main(String[] args){SetStudent set new HashSetStudent();set.add(new Student(zhangsan,31));set.add(new Student(lisi,23));set.add(new Student(wangwu,21));printCollection(set);ListWorker list new ArrayListWorker();list.add(new Worker(xiaoqiang, 45));list.add(new Worker(huaan, 41));list.add(new Worker(daming, 47));printCollection(list);ListString list2 new ArrayListString();list2.add(xiaoqiang);list2.add(huaan);list2.add(daming);printCollection(list2);}public static void printCollection(Collection? list){for (Iterator? it list.iterator(); it.hasNext();) {System.out.println(it.next());}} } 无法确定具体集合中的元素类型是什么就可以使用泛型的通配符机制来完成。 总结 当使用泛型类或者接口时传递的具体的类型不确定可以通过通配符(?)表示。但是一旦使用泛型的通配符机制后只能使用Object类中的共性方法集合中元素自身方法无法使用。 3.2、泛型限定 如果想要对被打印的集合中的元素类型进行限制只在指定的一些类型进行打印。怎么做呢 例如 在上述例子中只需要打印学生和工人的集合。找到学生和工人的共性类型Person使用泛型的限定。 ? extends Person : 接收Person类型或者Person的子类型。 public static void printCollection(Collection ? extends Person list){for(InteratorCollection? extents Person it list.interator();it.hasNext();){System.out.println(it.next());} }限定泛型的上限? extends E :接收E类型或者E的子类型。 限定泛型的下限? super E :接收E类型或者E的父类型。 当在集合或者其他地方使用到泛型后那么这时一旦明确泛型标识的类型那么在使用的时候只能给其传递和标注类型匹配的类型否则就会报错。 八、异常 1、概述 1.1、异常和错误的区别 异常程序在运行期间发生了异常通常可以有针对性的处理方式。错误程序在运行期间发生了错误通常不会有针对性的处理方式。错误的发生往往都是 系统级别的问题都是Jvm所在系统发生的并反馈给-vm的无法针对处理只能修正代码 class ExceptionDemo {public static void main(String[] args) {int[] arr new int[3];System.out.println(arr[0]);System.out.println(arr[3]);//该句运行时发生了ArrayIndexOutOfBoundsException导致程序无法继续执行。程序结束。System.out.println(over); //由于上面代码发生了异常此句代码不会执行} }1.2、异常发生的过程 1、运行时发生了问题这个问题JVM认识这个问题java本身有 2、描述描述内容有问题的名称、问题的内容、问题的发生位置既然有这么多的信 息java就将这些信息直接封装到对象中。 3、抛出jvmjvm进行最终处理将问题的名称信息位置都显示屏幕上。 1.3、异常的应用 在编写程序时必须要考虑程序的问题情况。比如在写功能时需要接受参数在使用功能中使用接受到的参数时首先需要先对参数数据进行合法的判断数据若不合法应该告诉调用者传递合法的数据进来。这时需要使用异常这种方法来告诉调用者。所以定义程序需要考虑程序的健壮性。 异常应用例如 //描述人 class Person{private String name;private int age;Person(String name,int age){//加入逻辑判断。if(age0 || age200){/*//System.out.println(年龄数值错误);//return;//终止初始化。这样做虽然可以编译并运行看到提示消息但是问题却依然发生程序还在继续执行。并打印p对象。这是不合理的。人对象初始化过程中已经出了问题为什么要会对人对象操作所以应该将问题暴露出来让使用该程序的调用者知道。所以要使用异常来解决。*/throw new IllegalArgumentException(age,年龄数值非法);}this.name name;this.age age;}//定义Person对象对应的字符串表现形式。覆盖Object中的toString方法。public String toString(){return Person[namename,ageage];} } class ExceptionDemo4 {public static void main(String[] args) {Person p new Person(xiaoming,-20);System.out.println(p);} } 1.4、自定义异常 之前的几个异常都是java通过类进行的描述。并将问题封装成对象异常就是将问题封装成了对象。这些异常不好认书写也很不方便能不能定义一个符合我的程序要求的问题名称。既然JDK中是使用类在描述异常信息那么我们也可以模拟Java的这种机制我们自己定义异常的信息异常的名字让异常更符合自己程序的阅读。准确对自己所需要的问题进行类的描述。 2、异常体系 Throwable 是异常和错误的超类(父类)它是异常体系的顶层类 自定义异常产生问题应该怎么解决呢 自定义异常被抛出必须是继承Throwable或者继承Throwable的子类。该对象才可以被throw抛出。 这个异常体系具备一个特有的特性可抛性可以被throw关键字操作。 异常继承选择父类时更为确切是继承Exception。 例如 class NoAgeException extends Exception{/*为什么要定义构造函数因为看到Java中的异常描述类中有提供对问题对象的初始化方法。*/NoAgeException() {}NoAgeException(String message) {} }这个版本还是编译失败因为没有声明RuntimeException描述中有明确说明这个运行时异常以及其子类都无需进行声明。可以将自定义的异常继承RuntimeExceptio。 但是缺少异常提示信息父类构造函数中有关于异常信息的操作那么在自己定义的异常中需要将这些信息传递给父类让父类帮我们进行封装即可。 例如 class NoAgeException extends RuntimeException{/*为什么要定义构造函数因为看到Java中的异常描述类中有提供对问题对象的初始化方法。*/NoAgeException(){super();}NoAgeException(String message) {super(message);// 如果自定义异常需要异常信息可以通过调用父类的带有字符串参数的构造函数即可。} } 3、异常的分类  1、Exception异常 在函数内抛出Exception编译失败因为编译器在检查语法时发生了错误。该程序已经出现问题Java认为这个程序本身存在隐患需要捕获或者声明出来(你要么把问题处理要么把问题标识出来让调用知道)。 2、RuntimeException异常 这个异常不需要捕捉和声明为什么呢不是功能本身发生的异常而是因为比如调用者传递参数错误而导致功能运行失败。这也是问题需要通过异常来体现但是这个异常不要声明出来的。 4、声明和捕获 声明将问题标识出来报告给调用者。如果函数内通过throw抛出了编译时异常而没有捕获那么必须通过throws进行声明让调用者去处理。 捕获Java中对异常有针对性的语句进行捕获。 捕获格式 try {//需要被检测的语句。 } catch(异常类 变量)//参数。 {//异常的处理语句。 }finally {//一定会被执行的语句。 }应用 class NoAgeException extends RuntimeException{NoAgeException() {super();}NoAgeException(String message) {super(message);} } class Person{private String name;private int age;Person(String name,int age)//throws NoAgeException {//加入逻辑判断。if(age0 || age200) {throw new NoAgeException(age,年龄数值非法);}this.name name;this.age age;}//定义Person对象对应的字符串表现形式。覆盖Object中的toString方法。public String toString() {return Person[namename,ageage];} } class ExceptionDemo{public static void main(String[] args) {try{Person p new Person(xiaoming,20);System.out.println(p);}catch (NoAgeException ex){System.out.println(异常啦);}System.out.println(over);} }构造函数到底抛出这个NoAgeException是继承Exception呢还是继承RuntimeException呢 继承Exception必须要throws声明一声明就告知调用者进行捕获一旦问题处理了调用者的程序会继续执行。 继承RuntimeExcpetion,不需要throws声明这时调用是不可能编写捕获代码的因为调用根本就不知道有问题。一旦发生NoAgeException调用者程序会停掉并有jvm将信息显示到屏幕让调用者看到问题修正代码。 throw和throws区别 throw用在函数内。throws用在函数上。thorw抛出的是异常对象。throws用于进行异常类的声明后面异常类可以有多个用逗号隔开。 5、finally关键字 有一些特定的代码无论异常是否发生都需要执行。因为异常会引发程序跳转导致有些语句执行不到。无法满足这个需求。异常捕获处理时java提供解决方案finally就是解决这个问题的这个代码块中存放的代码都是一定会被执行。 应用例如 void add(Data data)throws NoAddException{//1、连接数据库。try{//2、添加数据。//添加数据时发生了异常情况。throw new SQLException();程序跳转就执行不到断开连接。//而断开连接必须要执行因为不执行连接资源在浪费。//无论是否发生问题都需要执行断开连接的动作从而释放资源。}catch(SQLException e){//解决数据库的问题。//同时将问题告诉调用者。throw new NoAddException();}finally{//3,断开连接。} }只要程序中使用到了具体的资源(数据库连接IO资源网络连接socket等)需要释放都必须定义在finally中。你在定义程序只要问题发生与否指定程序都需要执行时就定义finally中。包括return的内容也会直接执行。 异常在方法复写中细节 异常在继承或者实现中的使用细节 子类覆盖父类方法时如果父类的方法声明异常子类只能声明父类异常或者该异常的子类或者不声明。越来越精细当父类方法声明多个异常时子类覆盖时只能声明多个异常的子集 越来越精细。当被覆盖的方法没有异常声明时子类覆盖时无法声明异常的。 举例父类存在这种情况接口也有这种情况。 问题接口中没有声明异常而实现的子类覆盖方法时发生了异常怎么办 无法进行throws声明只能catch的捕获。万一问题处理不了呢catch中继续throw 抛出但是只能将异常转换成RuntimeException子类抛出。 九、反射 反射是框架设计的灵魂它将类成员其他部分封装成对象。 使用的前提条件必须先得到代表的字节码的classClass类用于表示.class文件字节码 1、反射的概述 反射机制是在运行状态中对于任意一个类都能够知道这个类的所有属性和方法对于任意一个对象都能够调用它的任意一个方法和属性这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 总结反射就是把Java类中的各种成分映射成一个个Java对象。 例如一个类有成员变量、方法、构造方法、包等等信息利用反射技术可以对一个类进行解剖把个个组成部分映射成一个个对象。 反射的好处 运行过程中操作各种类的对象。可以解耦提高可拓展性。 2、反射的使用 2.1、获取类 编写流程 先写一个Student类获取Class对象的三种方式 1.Object ----》 getClass(); 2.任何数据类型包括基本数据类型都有一个静态的 class 属性。 3.通过Class类的静态方法forNameString className。 public class Fanshe {public static void main(String[] args) {//第一种方式获取Class对象 Student stu1 new Student();//new的时候 产生一个Student对象一个Class对象。Class stuClass stu1.getClass();//获取Class对象System.out.println(stuClass.getName()); //这个方法多此一举属于脱裤子放屁第二种方式获取Class对象Class stuClass2 Student.class();System.out.println(stuClass stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个.是同一个//第三种方式获取Class对象try{Class StuClass3 class.forName(Student); //注意此字符串必须是真实路径就是带包名的类路径包名.类名System.out.println(stuClass3 stuClass2);//判断三种方式是否获取的是同一个Class对象}catch(ClassNotFoundExcepyion e){e.printStackTrace();}} }注意在运行期间一个类只有一个Class对象产生。 三种方式常用第三种第一种对象都有了还要反射干什么。第二种需要导入类的包依赖太强不导包就抛编译错误。一般都第三种一个字符串可以传入也可写在配置文件中等多种方法。 2.2、获取构造方法并 //通过Class对象可以获取某个类中的构造方法、成员变量、成员方法并访问成员 public static void main(String[] args) throws Exception {//1.加载Class对象Class cls Class.forName(Student);//2.获取所有公有构造方法Constructor[] conArray cls.getConstructors();for(Constructor c : conArray){System.out.println(c);}//3.获取所有构造方法conArry cls.getDeclaredConstructors();for(Constructor c : conArray){System.out.println(c);}//4.获取公有、无参的构造方法Constructor con cls.getConstructor(null);//1.因为无参所以类型是null注意是类型而不是无参才些null//2.返回描述这个无参构造函数的类对象//调用构造方法con cls.getDeclaredConstructor(char.class);//参数类型.class,多个用,隔开。Object obj con.newInstance(我); }newInstance是 Constructor类的方法管理构造函数的类 2.3、获取并调用成员变量 例如 public class Student {public Student(){}public String name;protected int age;char sex;private String phoneNum;Overridepublic String toString() {return Student [name name , age age , sex sex , phoneNum phoneNum ];} } class Text{public static void main(String[] args) throws Exception {//1.获取class对象Class cls Class.forName(Student);//2.获取所有公有字段Field[] fieldArray cls.getField();for(Field f : fieldArray){System.out.println(f);}//3.获取所有的字段fieldArray stuClass.getDeclaredFields();for(Field f : fieldArray){System.out.println(f);}//4.调用Field f cls.getField(name);Object obj cls.getConstructor().newInstance();//产生Student对象,相当于 Student s new Student();//为字段设置值f.set(obj, 刘德华);//为Student对象中的name属性赋值--》stu.name 刘德华} }由此可见 调用字段时需要传递两个参数。 第一个参数要传入设置的对象第二个参数要传入实参 2.4、获取并调用成员方法 public class Student {public void show1(String s){System.out.println(调用了公有的String参数的show1(): s s);}protected void show2(){System.out.println(调用了受保护的无参的show2());}void show3(){System.out.println(调用了默认的无参的show3());}private String show4(int age){System.out.println(调用了私有的并且有返回值的int参数的show4(): age age);return abcd;} } class MethodClass {public static void main(String[] args) throws Exception {//1.获取Class对象Class cls Class.forName(Student);//若是包下的Class则用.点出来//2.获取所有公有方法Method[] methodArray cls.getMethods();for(Method m : methodArray){System.out.println(m);}//3.获取所有的方法methodArray cls.getDeclaredMethods();for(Method m : methodArray){System.out.println(m);}//4.获取公有的show1()方法Method m cls.getMethod(show1,String.class);//实例化一个Student对象Object obj cls.getConstruct().newInstance();m.invoke(obj,刘德华);//5.获取私有的show4()方法m cls.getDeclaredMethod(show4, int.class);m.setAccessible(true);//暴力解除私有限定Obj result m.invoke(obj,20);} }2.5、反射main方法 public class Student {public static void main(String[] args) {System.out.println(main方法执行了。。。);} } /*** 获取Student类的main方法、不要与当前的main方法搞混了*/ class Main {public static void main(String[] args) {try{//1、获取Student对象的字节码Class clazz Class.forName(Student);//2、获取main方法Method methodMain clazz.getMethod(main, String[].class);//第一个参数方法名称第二个参数方法形参的类型//3、调用main方法//methodMain.invoke(null, new String[]{a,b,c});//第一个参数对象类型因为方法是static静态的所以为null可以第二个参数是String数组这里要注意在jdk1.4时是数组jdk1.5之后是可变参数//这里拆的时候将 new String[]{a,b,c} 拆成3个对象。。。所以需要将它强转。//方式一methodMain.invoke(null, (Object)new String[]{a,b,c});//方式二//methodMain.invoke(null, new Object[]{new String[]{a,b,c}});}catch(Exception e){e.printStackTrace();}} }2.6、通过反射越过泛型检查 /** 通过反射越过泛型检查* 例如:有一个String泛型的集合怎样能向这个集合中添加一个Integer类型的值*/ public class Demo {public static void main(String[] args) throws Exception{ArrayListString strList new ArrayList();strList.add(aaa);strList.add(bbb);// 获取ArrayList的Class对象反向的调用add()方法添加数据Class listClass strList.getClass(); //得到 strList 对象的字节码 对象// 获取add()方法Method m listClass.getMethod(add, Object.class);//两个参数第一个方法名称第二个参数类型// 调用add()方法m.invoke(strList, 100);// 遍历集合for(Object obj : strList){System.out.println(obj);}} }
http://www.pierceye.com/news/46187/

相关文章:

  • 做网站用商标吗最新军事新闻头条
  • 长沙专业建设网站企业岳阳新网网站建设有限公司
  • 男做暧免费视频网站网站推广方式推荐
  • 制作商城版网站开发大网站制作公司
  • 网站建设课网站免费建立
  • 做一个网站价格网站广告位价格一般多少
  • Hdi做指数网站wordpress添加html页面
  • 广州 网站的设计公司怎么学做电商然后自己创业
  • 哪个网站可以做微信引导图推广资源整合平台
  • 昆明网站开发公司电话网站建设的一些销售技巧
  • 广州seo网站推广公司地方购物网站盈利模式
  • 高端企业建站公司免费下载应用市场
  • 网站开发岗位思维导图刷关键词要刷大词吗
  • 网站规划与开发牛魔王网站建设
  • 织梦做的网站首页打不开wordpress新建html
  • 苏州建设网站服务中国制造网网站建设的优势
  • 福田汽车官网报价大全光泽网站建设wzjseo
  • 网站模板 介绍注册电子邮箱免费注册
  • 上海做网站建设公司wordpress页面怎么编辑器
  • 专业郑州做网站招投标相关政策
  • 网页设计师必须知道的网站专做动漫解说的网站
  • 深圳网站建设深正互联ps做简洁大气网站
  • 网站空间到期提示wordpress主题2019
  • 网站服务器有哪些家装设计平台
  • 时尚网站设计wordpress询盘功能
  • 自适应网站 与响应式外包公司驻场能不能去
  • 个人网站备案模板电子商务网站建设书
  • wordpress 仿花瓣优化建站
  • 网站换服务器对网站排名有影响吗wordpress 域名更换
  • 免费手机个人网站网络舆情分析的免费网站