您的位置:首页 > 其它

内部类,接口,抽象类 比较(11)

2015-11-01 12:14 465 查看
Math方法  static double pow(double a,
double b) 返回第一个参数的第二个参数次幂的值。

如果d=3.14; d++;  结果d等于 4.140000000000001  为什么?double会有精度损失,可以使用BigDecimal完成不失精度的计算

方法的重载和重写:

重载:定义在一个类中,方法名相同,参数列表个数、顺序、类别不同;修饰符和返回值可以相同可以不同。一个类中的多态。可以抛出不同的异常;

重写:定义在继承或实现的两个类中,方法名、参数列表、返回值都相同;修饰符只能比父类范围大,super可以引用父类的方法。两个类中多态。不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。

内部类:

               /*

                * 内部类作为成员国方法,可以直接访问外部类的所有成员。

                * 1.通过新建Outer对象在创建Inner对象

                * 2.可以直接调用Outer的其他成员(静态和Private都可以),不用前缀

                * Outer out =
new Outer();

                * Inner in = out.new
Inner();                //或者
Inner in = new Outer().new Inner() ;

                */

               

               /*

                * 内部类作为静态成员

                * 1.直接通过Outer类名创建对象
//  Outer.Inner in = new Outer.Inner();

                * 2.Inner 只能访问Outer类中的静态成员和方法

                */

               

               /*

                * 内部类作为静态成员变量的静态方法

                * 不用创建对象,直接调用方法
Outer.Inner.showInner();

                */

               

               /*

                * 内部类作为外部类成员方法中

                * 1.外部不可以直接创建内部类

                * 2.内部类中方法可以调用外部类的成员(非fainl也可以)

                * 3.内部类中调用外部类方法中的变量,该变量必须加final,变成常量。原因是生命周期不同。详细见下

                *

                * 方法中的内部类为什么不能访问方法中的局部变量? 

                *   内部类的生命周期和方法中的局部变量是不一样的,内部类是也是一个类,是存储在堆中,也只有当对该类的引用消失时,

                * 内部类才会消亡,而方法的局部变量是存储在栈内存中的,当调用结束时就会弹栈,就是在内存中这个属性就消失了。

                * 内部类的生命周期超过了方法中局部变量的生命周期,内部类可能会调用到已经消失的局部变量,因此内部类不能直接访问方法中的局部变量。

               
      * 解决方法:

                * 局部变量前加修饰符final,此时局部变量就会存在堆中,生命周期和内部类的生命周期是一样的,此时内部类就可以访问方法中的局部变量。

                */

               

               /*

                * 匿名内部类,直接调用方法,方法不应超过两个

                * 1.直接创建父类构造器,编写自己类的方法,直接调用方法,也可以赋值给一个变量

                * new Object(){

                *  
             int c
= 2 ;

                *  
             public void show(){

                *  
                     System.out.print(a+"byb...run");

                *  
                     }

                *  
     

                *  
             }.show();

                * 2.当直接调用方法是可以调用父类没有自己特有的方法

                *   当赋值给变量时只可以调用父类中已有的子类重写的方法,向上转型隐藏子类特有的方法

                */

接口和抽象类的总结:

1.abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。

  2.在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据

成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。

  3.abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,

interface表示的是"like-a"关系。

4.接口一般用于在抽象类中没有可供继承的默认实现时(即没有实例变量和默认方法实现)代替该类。

5.abstract class是另一种契约形式,是设计对实现的要求;而接口是服务器对客户端的要求。

6.abstract class是一个基类,不能被实例化;接口是个声明,每个对应接口的类都要实现方法。

7. 一个子类如果implements一个接口,就必须实现接口中的所有方法(不管是否需要);如果是继承一个抽象类,只需要实现需要的方法

即可,这是抽象类的一个优点

8. 如果一个接口中定义的方法名改变了,那么所有实现此接口的子类显然将无法通过编译,因为它们所实现的方法名已经不存在了,这是

接口的一个缺点;而抽象类中如果有个非抽象方法改了,就不存在这个问题,只是为子类添加了一个新的方法。

9. 看前面两点,似乎抽象类要比接口有着更多的优点,但它却有着一个难以弥补的缺点:就是一个子类只能有一个父类。A extends B 。

这样A就拥有了B的所有方法和功能,但当A还想拥有C的功能的时候。就不能通过 A extends C 来实现,而需要走一些弯路。目前系统架构

的趋势就是由针对抽象(借口,抽象类)而不是具体编程,并且将功能尽可能的细分。这就需要通过实现多个接口的方式来实现,显然,抽

象类无法提供这样的功能。从系统重构的角度来说,一个具体类抽象出接口是十分方便的。只需要写一个接口,里面定义具体类的所有方法,

然后在为这个具体类implement这个接口就可以了。而抽象类就要复杂的多,比如说 B extends A , C extends B 如果想要为c抽象出一个抽象

类D的话,就需要找到它的最顶层A来从头做起,因为无法做到C extends D 

/*

* 打印空心三角形i列,

*/

public class test02
{

       public static void main(String[]
args) {

               int[]
arr = {1,2,3,4,5,};

               for(int i
: arr)

                       System.out.println(i);

               int i
= 29; // 输入一个基数组成三角

               for (int x
= (i - 1) / 2, z = 0; x < (i - 1); x++, z++) {

                       int y
= 0;

                       while (y
<= x) {

                               if (y
== x)

                                 
     System.out.println("*");

                               else if (x
- 2 * z == y)

                                 
     System.out.print("*");

                               else

                                 
     System.out.print("
");

                               y++;

                       }

               }

               while (i
> 0) {

                       if (i
% 2 != 0)

                               System.out.print("*");

                       else

                               System.out.print("
");

                       i--;

               }

       }

}

========================================

/*

* 循环从键盘接受的输入的多个字符,知道输入“end”时循环结束,并将所有输入的字符串按字典倒序打印。

*/

public class test01
{

       public static void main(String[]
args) {

               ArrayList<String> arr = new ArrayList<String>();//
创建容器

               Scanner scanner = new Scanner(System.in);//
创建键盘扫描

               while (scanner.hasNext())
{

                       String s = scanner.next();

                       if (s.equals("end"))//
判断输入的字符串等于end退出循环

                               break;

                       arr.add(s);//
不等于,添加到容器

               }

               Collections.sort(arr); //
排序,从小到大

               Collections.reverse(arr);//
强行逆序

               for (String
s : arr)// 便利

                       System.out.println(s);

       }

}

=========================================

/*

* 将指定目录下所有的txt文件复制到c盘下任意目录(你可以自己指定路径)并在复制后将txt后缀改成java后缀名。

*/

public class Test03
{

       public static void main(String[]
args) throws IOException {

               // 定义两端的文件目录

               String old_file = "e:\\test";

               String new_file = "d:\\Demo";

               File oldfile = new File(old_file);

               File newfile = new File(new_file);

               // 查找文件中所有的。txt文件

               ArrayList<File> arr = new ArrayList<File>();

               arr = findTxt(oldfile,
arr);

               // 复制到目录检查,没有则创建该目录

               if (!newfile.isDirectory())

                       newfile.mkdirs();

               // 便利集合分别复制每个文件

               for (File
f : arr) {

                       //
调用方法返回新名字

                       File newf = newFiles(f,
newfile);

                       //
复制文件

                       move(f,
newf);

               }

       }

       // 将原来的.txt文件转变为.java文件对象

       private static File
newFiles(File f, File newfile) {

               // 变换文件名

               String name = f.getName();

               name = name.replace(".txt", ".java");

               File file = new File(newfile,
name);

               return file;

       }

       // 通过流复制文件

       private static void move(File
f, File newf) throws IOException {

               BufferedReader buffr = new BufferedReader(new FileReader(f));

               BufferedWriter buffw = new BufferedWriter(new FileWriter(newf));

               String line = null;

               while ((line
= buffr.readLine()) != null)

                       buffw.write(line);

               buffr.close();

               buffw.close();

       }

       // 通过递归找出所有.txt文件

       private static ArrayList<File>
findTxt(File oldfile, ArrayList<File> arr)

                       throws IOException
{

               File[] files = oldfile.listFiles();

               for (File
f : files) {

                       if (f.isDirectory())
{

                               findTxt(f,
arr);

                       } else {

                               if (f.getAbsolutePath().endsWith(".txt"))

                               //
System.out.println(f.getAbsolutePath());

                               {

                                 
     arr.add(f);

                               }

                       }

               }

               return arr;

       }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: