总结--看帖收“货”
看帖收“货”
这个总结帖的意思就是自己在网上浏览其他人的帖子或者技术时对自己的一些新的启发,在这楼主只接触了不到半年的java,如果错误请各位指出,此贴长时间持续更新....
1. 引用帖子位置:http://blog.csdn.net/chenssy/article/details/12757911 非常感谢
帖子内容:这个是对于封装的帖子,在我们进行封装一个类的时候,如下
public class Student { private String name; private Integer sno; //private String sno public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getSno() { //public String getSno() { return sno; } public void setSno(Integer sno) { this.sno = sno; //this.sno = String.valueOf(sno);转换即可 } }
帖子启发:上面是一个简单的Student的实体类,在我们项目中如果有要求,Student 的 sno改为String类型的话,我们直接更改对应的属性的setter即可,如上注释!!!,同样的也可以在getter方法中加入判断,如下
public class Student { private String name; private Integer sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { if(this.sex==1) { return "男生"; } return "女生"; } public void setSex(Integer sex) { this.sex = sex; } } //======================================= public class Demos{ public static void main(String[] args) { Student stu = new Student(); stu.setSex(2); String sex = stu.getSex(); System.out.println(sex); } } output:女生
帖子启发:个人感觉在hibernate等dao框架中,自动赋值之后也可以通过这样的方式来取得String类型的属性值!!
******************************************************************************************************************************************************************************
2. 引用帖子位置:http://blog.csdn.net/thinkGhoster/article/details/2307001 非常感谢
帖子内容:这张帖子是关于java的多态的内容的,下面是一个多态的一个小例子:
public class A { public String show(D obj) { return ("A and D"); } public String show(A obj) { return ("A and A"); } } //---------------------------------------------- public class B extends A{ public String show(B obj){ return ("B and B"); } public String show(A obj){ return ("B and A"); } } //---------------------------------------------- public class C extends B{ } //---------------------------------------------- public class D extends B{ } //---------------------------------------------- public class Test { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println("1--" + a1.show(b)); System.out.println("2--" + a1.show(c)); System.out.println("3--" + a1.show(d)); System.out.println("4--" + a2.show(b)); System.out.println("5--" + a2.show(c)); System.out.println("6--" + a2.show(d)); System.out.println("7--" + b.show(b)); System.out.println("8--" + b.show(c)); System.out.println("9--" + b.show(d)); } }
output:
1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D
为什么会产生以上的输出结果呢?其实在继承链中对象方法的调用存在一个优先级问题:
1. this.show();
2. super.show();
3. this.show((super)o);
4. super.show((super)o);
拿两个输出作解释:
1. 第四个输出:4--B and A:我们可以看到这个程序中第四个输出这样调用的方法 a2.show(b),其中a2的定义为:A a2 = new B();所以上述优先级中的this就为A类型,调用方法的参数为B类型,其b参数定义为 B b = new B();我们一步步的往下分析,首先是第一个优先级this.show(),因为a2是A的变量,所以在这this就是A, 在A中去寻找有没有符合b参数的方法,显然是没有的,然后到优先级2:super.show(),去寻找其A类的父类中是否有这个方法,由于A并没有显示继承的父类,不计Object,所以优先级2无法满足,轮到了优先级3:this.show((super)o);这个中的o就为参数b,其类型就是B类型,(super)o 就等于A类型,因为B继承了A ,与优先级1中类似,去A中寻找去寻找参数为A类型的方法,找到了参数为A的方法,但是B类中重写了此方法,所以输出为B and A;
2. 第五个输出:5--B and A:这次的调用方法的方式为a2.show(c),a2类型是不变的,还是A类型,参数变为c,c变量的定义为: C c = new C();由于a2还是A的定义的变量,所以this还是为A,分析:优先级1:A类中并没有一个参数为c的方法,所以不满足就到了优先级2,其中A是没有父类的,所以优先级2也是无法满足的,优先级3:(super)o中o为C类,其C类的父类有A与B,所以去A中寻找对应的方法,发现有A没有B参数的方法,但是A的子类B重写了A的方法,所以就输出了B中的A方法。
帖子启发:多态机制遵循的原则概括为:当父类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,自我理解:不对请多指正:就是用谁定义的此变量,那么就决定了调用谁中的成员方法,但是前提是被调用的方法是在父类中定义过的,当执行代码的时候,如果实现类中实现了父类中的方法,那么会执行实现类中重写后的方法。
******************************************************************************************************************************************************************************
3. 引用帖子位置:http://blog.csdn.net/chenssy/article/details/12858267 非常感谢
帖子内容:这张帖子是关于接口以及抽象类的,下面我总结一下自己看完后的收获,不对请指正偶
先把抽象类以及接口的注意问题总结一下
抽象类:1. 抽象方法是不能实例化的,实例化的工作应该交给其子类完成,此对象是干什么的,是由子类决定,例子如下,从例子中就可以看到,谁实现的此抽象类,那么就会执行此类中实现了父类中的抽象的方法的方法,与继承类似类似,如果没有实现父类中的非抽象方法,那么就会执行父类中的非抽象方法,子类如果实现了非抽象方法,那么就执行子类中非抽象的方法
public abstract class MyDemo { public abstract void say(); public void work() { System.out.println("MyDemo work"); } } //--------------------------------------------------------------- public class MyDemoExDog extends MyDemo{ @Override public void say() { System.out.println("汪汪汪"); } public void work() { System.out.println("汪汪汪 work 看门"); } } //--------------------------------------------------------------- public class MyDemoExPeople extends MyDemo{ @Override public void say() { System.out.println("Hello 你好"); } } //--------------------------------------------------------------- public class Test { public static void main(String[] args) { MyDemo people = new MyDemoExPeople(); people.say(); people.work(); MyDemo dog = new MyDemoExDog(); dog.say(); dog.work(); } } //--------------------------------------------------------------- output: Hello 你好 MyDemo work 汪汪汪 汪汪汪 work 看门
2. 抽象方法必须由子类重写,以上代码就可以看出来了、
3. 只要包含一个抽象方法的类,那么必须定义为抽象类、
4. 抽象类中可以包含非抽象方法,也可以包含抽象方法、
5. 子类中的抽象方法 不能与父类中的抽象方法同名、(java 9 好像可以。)
6. abstract final不能同时修饰一个类、
7. abstract 不能与private、static、final或native并列修饰同一个方法、
接口:1. 接口中定义的变量都为常量:public static final,必须初始化、其他类使用的时候直接Interface.FieldName即可调用,无需实现此接口
2. 接口中定义为方法都为public,不显示定义默认为public、
3. 接口中不存在实现的方法,(java8 更新后是可以有实现代码的如下)
public interface DD { public static void cc() {System.out.println("ccc");} public default void dd() {System.out.println("ddd");} } //---------------------------------------------------------------- class T{ public static void main(String[] args) { DD.cc(); } } //---------------------------------------------------------------- class E implements DD{ public static void main(String[] args) { DD.cc(); DD d = new E(); d.dd(); } } //----------java 8 中更改了接口,可以定义static方法和default方法,static方法直接用interface.methodName调用即可,default则必须用用实例化后的对象来调用,注意子类中的方法不能与接口中default方法名重复------------------------------------------------------ output: ccc ddd
4. 实现了接口之后,必须实现其非static 和 default 修饰的方法,抽象类可以不需要实现、
5. 不能new,只能用子类实例化接口
好了,到此就是接口以及抽象类的注意事项,下面是一个小例子,使我的到了一些收获
并没有代码,现在有一个门的对象Door,熟知Door有一个开门以及关门的功能,这是一个门的最基本的功能,那么我们如果在写完后再次修改门对象的定义,需要添加一个报警功能,那么我们该怎么办,如果在抽象类中直接添加报警功能,如果是抽象方法,就必须重写,如果是父类已经实现的方法,子类如果在细化实现的话,那么也要重写,这是一种方法,但是如果一直有改动或者方法很多的话,那么这个抽象类将变得相当麻烦,第二种方法就是:在不更改抽象类的情况下,可以编写一个报警的接口,用子类来实现他,那么子类就必须去实现此方法,这样就可以达到不做抽象类的更改并添加了报警功能。
抽象类的编写就是基于子类的共同特性的,它是描述一个类的大致情况的,外貌轮廓,接口则是行为形式,描述是具体干什么的,如果一个工厂有什么部门,那么如果按照第一种方法,再去每个部门添加部门具体是做什么的,那么不仅仅影响到了继承他的子类,而且使代码变的不太容易维护,杂乱,采用第二种,可以避免这种情况,子类需要什么功能就实现什么接口,更加的灵活
帖子启发:抽象类的实现就是基于子类的共同特性的,它是描述一个类的大致情况的,外貌轮廓,接口则是行为形式,描述是具体干什么的,在使用的时候,我们可以将相同子类的共同特性抽检出一个抽象类来作为其子类的大致轮廓,具体实现细节,可以编写接口并实现即可、一个类继承一个抽象类。抽象类规定了子类的大概轮廓,其具体实现的方法,可以使用抽象类中的,也可以通过实现接口,重写接口中的方法来实现子类的细化、可以利用抽象类和借口配合使类更具体
******************************************************************************************************************************************************************************
4. 引用帖子位置: http://blog.csdn.net/chenssy/article/details/13024951 非常感谢
帖子内容: 这篇帖子是关于内部类的说明的帖子,总结如下
1. 每个内部类都可以直接继承实现一个类或者接口,所以无论外部类继承了什么类,对于内部类都没有影响、
2. 接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更完整、
3. 内部类提供了更好的封装,除了该外围类,其他类都不能访问。
内部类简单代码:
public class EE {//父类 static int c = 5; public void dd() { System.out.println("dsdsdsdsddsdsds"); } } //---------------------------------------------------------------------- public class My extends EE{ private int x = 0; private int x1 = 01; public static void main(String[] args) { My m = new My(); My.MyA myA = m.new MyA();//创建内部类对象方式 myA.meth();//调用内部类对象方法 System.out.println(myA.y);//调用内部类对象属性 } @Override public void dd() {//重写的父类的方法 System.out.println("dsdsdsdwwwwwww"); } class MyA{ private int y = 0; public void meth() { System.out.println(x+"d");//可以直接调用外部类的成员变量 System.out.println(My.this.x1);//第二种方式 My.this.dd();//调用外部类方法 } } }
成员内部类:就是上面这种情况
1. 成员内部类中不能有static变量和方法,
2. 成员内部类是依附外围类的,只有创建了外部类的实例,才能创建内部类,
3. 内部类可以无限制访问外部类资源包括private
局部内部类:就是嵌套在方法和作用域中的。
作用域中:
public class Parcel6 { private void internalTracking(boolean b){ if(b){ class TrackingSlip{ private String id; TrackingSlip(String s) { System.out.println("1"); id = s; } String getSlip(){ System.out.println("2"); return id; } } System.out.println("3"); TrackingSlip ts = new TrackingSlip("chenssy"); String string = ts.getSlip(); } } public void track(){ internalTracking(true); } public static void main(String[] args) { Parcel6 parcel6 = new Parcel6(); parcel6.track(); } }
output: 3 1 2
方法中:
public class Parcel5 { public Destionation destionation(String str){ class PDestionation implements Destionation{ private String label; private PDestionation(String whereTo){ label = whereTo; } public String readLabel(){ return label; } } return new PDestionation(str); } public static void main(String[] args) { Parcel5 parcel5 = new Parcel5(); Destionation d = parcel5.destionation("chenssy"); } }
匿名内部类:常用的就是按钮绑定事件
Button button = new Button(); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { //代码实现 } });
静态内部类:静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。
1、 它的创建是不需要依赖于外围类的。
2、 它不能使用任何外围类的非static成员变量和方法。
public class Big { private static int bigy = 2; private int bigx = 1; class Big1{ // private static int big1x = 3; 非静态方法中不允许出现静态方法以及变量 public void big1() { System.out.println(bigx);//System.out.println(Big.this.bigx); System.out.println(bigy);//System.out.println(Big.bigy); } } static class Big2{ private int big2y = 1; private static int big2x = 3; public void big2() { //System.out.println(x);静态内部类不能引用外部类的非静态方法 System.out.println("Big2 非静态方法执行"); System.out.println(big2x); } public static void big2_() { //静态内部类可以拥有静态以及非静态类型的属性以及方法 System.out.println("Big2 中静态方法执行"); } } public static void main(String[] args) { Big big = new Big(); Big1 big1 = big.new Big1();//非静态内部类实例化需要依靠外部类 Big2 big2 = new Big2();//静态内部类实例化不需要依靠外部类 big1.big1();//非静态内部类需要对象调用 big2.big2();//静态内部类中调用非静态方法 big2.big2_();//静态内部类中的调用静态方法1 Big2.big2_();//静态内部类汇中调用静态方法2 } }
帖子启发:无,
******************************************************************************************************************************************************************************
5. 引用帖子位置:http://blog.csdn.net/chenssy/article/details/14111307 非常感谢
帖子内容:是关于强制类型类型转换的。对于普通类型查api文档就可以,但是在开发中有时候会遇到类型转换异常:ClassCastException,如下
public class Father {} //------------------------------------------------------- public class Son extends Father{} //------------------------------------------------------- public class Castt { public static void main(String[] args) { Father father = new Father(); //father 的真身是Father // Son son = (Son)father; 出错 ClassCastException Father father2 = new Son(); //father2 的真身是Son Son son2 = (Son)father2;//所以转换不会出错 } }
帖子启发:如上代码就可以看出这个错出错的原因了,编译器在编译的时候只会检查类型之间是否有继承关系,有则通过,但是程序运行的时候,则会检查其真实类型,所以在继承类之间相互转换的时候,只有变量的真身是强转之后的类型的时候才会通过,否则失败、
******************************************************************************************************************************************************************************
6. 引用帖子位置: http://blog.csdn.net/chenssy/article/details/14486833#quote 非常感谢
帖子内容: 这篇帖子是关于构造函数,静态代码块,以及构造代码块的。感觉明白其执行顺序以及作用就可以
public class Snippet { public Snippet() { System.out.println("父类"); } } //--------------------------------------------------------------------- public class StaticM extends Snippet{ public StaticM() { System.out.println("构造"); } { System.out.println("构造代码块2"); } { System.out.println("构造代码块1"); } static { System.out.println("Sdsds"); } public static void main(String[] args) { StaticM staticM = new StaticM(); } } output: Sdsds 父类 构造代码块2 构造代码块1 构造
帖子启发:从上面就可以看出执行顺序,如果该类存在父类并且父类拥有构造方法,那么执行顺序为:本类的静态代码块 > 父类构造方法 > 本类构造代码块 > 本类构造函数,如果父类也拥有构造代码块,那么他的执行顺序是先于父类构造方法执行的, 本类的静态代码块 > 父类构造代码块 > 父类构造方法 > 本类构造代码块 > 本类构造函数,
******************************************************************************************************************************************************************************
7. 引用帖子位置: http://blog.csdn.net/chenssy/article/details/17651909 非常感谢
帖子内容: 帖子的内容讲的是关于异常的,直接看代码就知道了
如下的文件1.txt是不存在的,注释部分为分别爆出来的异常。
public class TT { private void dd() { try { new FileInputStream(new File("d:/1.txt")); } catch (FileNotFoundException e) { e.printStackTrace(); /** * java.io.FileNotFoundException: d:\1.txt (系统找不到指定的文件。) * at java.base/java.io.FileInputStream.open0(Native Method) * at java.base/java.io.FileInputStream.open(Unknown Source) * at java.base/java.io.FileInputStream.<init>(Unknown Source) * at test2.TT.dd(TT.java:10) * at test2.TT.main(TT.java:16) */ } } public static void main(String[] args) { new TT().dd(); // String [] str = new String[2]; // System.out.println(str[2]); /* * Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 * at test2.TT.main(TT.java:20) * * */ } }
帖子启发:观察就能看出,用try-catch捕获输出的会显示错误信息,以及行数,而非try-catch捕获的代码,由于其他原因报错会显示Exception in thread "main",从这就能知道错误是出在try-catch语句块或者是其他地方了。
******************************************************************************************************************************************************************************
8. 引用帖子位置:
帖子内容:
帖子启发:
******************************************************************************************************************************************************************************
9. 引用帖子位置:
帖子内容:
帖子启发:
******************************************************************************************************************************************************************************
10. 引用帖子位置:
帖子内容:
帖子启发:
******************************************************************************************************************************************************************************
11. 引用帖子位置:
帖子内容:
帖子启发:
******************************************************************************************************************************************************************************
12. 引用帖子位置:
帖子内容:
帖子启发: