摘要:由于最近一个项目需要需要学习知识学习的过程中做了一些笔记主要以知识点记录为主现在分享出来供参考大部分内容是参考的自强学堂这里做了归纳接口在中接口可理解为对象间相互通信的协议接口在继承中扮演着很重要的角色接口只定义派生要用到的方法但方法的具体
由于最近一个项目需要,需要学习JAVA知识,学习的过程中做了一些笔记,主要以知识点记录为主,现在分享出来供参考.大部分内容是参考的自强学堂.这里做了归纳.
接口:
在JAVA中,接口可理解为对象间相互通信的协议,接口在继承中扮演着很重要的角色 接口只定义派生要用到的方法,但方法的具体实现完全取决于派生类
JAVA面向对象中支持的基本概念:
封装,继承,多态,抽象,类,对象,实例,方法,消息解析
类:
是一个模板,它描述一类对象的行为和状态,创建JAVA对象的模板
对象:
类的一个实例,有状态和行为
类变量:
声明在类中,方法体之外,但必须声明为static类型
构造方法:
在创建一个对象的时候,至少要调用一个构造方法,构造方法的名称必须与类同名,一个类可以有多个构造方法
创建对象:
需要三步:1.声明,声明一个对象,包括对象名称和类型 2.实例化,使用关键字new来创建一个对象 3.初始化,使用new创建对象时,会调用构造方法初始化对象 public class Puppy{ public Puppy(String name){ //这个构造器仅有一个参数:name System.out.println("Passed Name is :" + name); } public static void main(String[] args){ Puppy myPuppy = new Puppy("zhangtong"); } }
源文件声明规则:
一个源文件中只能有一个public类 一个源文件可以有多个非public类 源文件的名称应该和public的类名保持一致. 如果一个类定义在某个包中,那么package语句应该放在源文件的首行 如果源文件包含import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面 import语句和package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明
引用类型
引用类型变量由类的构造函数创建,可以使用它们访问所引用的对象. 对象、数组都是引用数据类型 所有引用类型的默认值都是null 一个引用变量可以用来引用与任何与之兼容的类型
常量
是一个固定值,不需要计算,直接代表相应的值,不能改变 final double PI = 3.1415926; 常量名一般大写 字面量可以赋给任何内置类型的变量 byte a = 68; char a = "A"; 字符串常量和字符常量都可以包括任何Unicode字符 char a = "u0001"; String a = "u0001";
转义字符
Java支持一些特殊的转义字符序列 换行 回车 f 换页符 退格 s 空格 制表符 " 双引号 " 单引号 反斜杠 ffffd 八进制字符 uxxx 16进制unicode字符
Java支持的变量类型
局部变量, 成员变量, 类变量(静态变量) 局部变量声明在方法,构造方法或者语句块中 局部变量在方法,构造方法,或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁 访问修饰符不能用于局部变量 局部变量只能在声明它的方法,构造方法或者语句块中可见 局部变量在栈上分配 局部变量没有默认值,所以局部变量被声明后,必须经过初始化才可使用 实例变量声明在一个类中,但在方法,构造方法和语句块之外 当一个对象被实例化之后,每个实例变量的值就跟着确定 实例变量在对象创建的时候创建,在对象销毁的时候销毁 实例变量的值应该至少被一个方法,构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量的信息 访问修饰符可以修饰实例变量 实例变量对于类中的方法,构造方法或者语句块是可见的,一般情况下应该把实例变量设为私有. 实例变量具有默认值,数值类型的默认值是0,布尔变量的默认值是false,引用类型变量的默认值是null. 类变量以static关键字声明,但必须在构造方法和语句块之外. 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝 静态变量除了被声明为常量外很少使用,常量是指声明为public/private, final 和 static类型的变量,常量初始化后不可改变 静态变量存储在静态存储区,经常被声明为常量 静态变量在程序开始时创建,在程序结束时销毁 与实例变量具有相似的可见性,但为了对类的使用者可见,大多数静态变量声明为public 静态变量可通过: ClassName.VariableName的方式访问 类变量被声明为public static final类型时,类变量名称必须使用大写字母. 如果静态变量不是public和final类型,其命名方式与实例变量以及局部变量的命名方式一致
访问控制修饰符
默认的,default,在同一包内可见,不使用任何修饰符 私有的, 以private修饰符指定,在同一类内可见 共有的, 以public修饰符指定,对所有的类可见 受保护的, 以protected修饰符指定,对 同一包内的类和所有子类 可见 接口里的变量都隐式声明为public static final,而接口里的方法默认情况下访问权限是public 类和接口不能被声明为private private访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据 如果几个相互访问的public类分布在不同的包中,则需要导入相应public类所在的包, 由于类的继承性,类所有的公有方法和变量都能被其子类继承 接口的成员变量和方法不能声明为protected
非访问修饰符
static修饰符,用来创建方法和类变量 final修饰符,用来修饰类,方法和变量,final修饰的类不能被继承,修饰的方法不能被继承类重新定义, 修饰的变量为常量,是不可修改的. abstract修饰符,用来创建抽象类和抽象方法 synchronized和volatile修饰符,主要用于线程的编程 static修饰符: 静态变量: static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有 一份拷贝.静态变量也被称为类变量. 静态方法: static 关键字用来声明独立于对象的静态方法, 静态方法不能使用类的非静态变量. 对类变量和方法的访问可以直接使用classname.variablename和classname.methodname的方式访问. final修饰符: final变量能被显式地初始化且只能初始化一次,被声明为final的对象的引用不能指向不同的对象. 但是final对象里的数据可以被改变.也就是说final对象的引用不能改变,但是里面的值可以改变 final修饰符通常和static修饰符一起使用来创建类常量 类中的final方法可以被子类继承,但是不能被子类修改 声明final方法 的主要目的 是防止该方法的内容被修改. abstract修饰符 抽象类: 不能用来实例化对象,声明抽象类的 唯一 目的是为了将来对该类进行扩充 一个类不能同时被abstract和final修饰.如果一个类包含抽象方法,那么该类一定要声明为抽象类 抽象类可以包含抽象方法和非抽象方法 抽象方法: 抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供.抽象方法不能同时被声明为final和static 任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类 synchronized修饰符 synchronized关键字声明的方法同一时间只能被一个线程访问. synchronized修饰符可以应用于四个访问修饰符. transient修饰符 序列化的对象包好被transient修饰的实例变量时,java虚拟机跳过该特定的变量 该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型 一般变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问 volatile修饰符 volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值. 当成员变量发生变化时,强迫线程将变化值回写到共享内存.这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值.
运算符
算数运算符,关系运算符,位运算符,逻辑运算符,赋值运算符,其它运算符 条件运算符(?:),也称为三元运算符 variable x = (expression) ? value if true : value if false instanceOf运算符:该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)
Java Number类
当需要使用数字的时候,我们通常使用内置数据类型,如: byte,int,long,double等 然鹅,在实际开发中,我们经常会遇到需要使用对象,而不是内置数据类型的情形, 为了解决这个问题,Java语言为每一个内置数据类型提供了对应的包装类 所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类Number的子类 这种由 编译器 特别支持的包装称为 装箱, 所以当内置数据类型被当作对象使用的时候, 编译器会把内置类型装箱为包装类.相似的,编译器也可把一个对象拆箱为内置类型. Number类属于java.lang包 Number类的成员方法 xxxValue(): 将number对象转换为xxx数据类型的值并返回 compareTo(): 将number对象与参数比较 equals(): 判断number对象是否与参数相等 valueOf(): 返回一个Integer对象指定的内置数据类型 toString(): 以字符串形式返回值 parseInt(): 将字符串解析为int类型 abs(): 返回参数的绝对值 ceil(): 对整形变量向左取整,返回类型为double型 floor(): 对整型变量向右取整。返回类型为double类型 rint(): 返回与参数最接近的整数。返回类型为double round(): 返回一个最接近的int、long型值 min(): 返回两个参数中的最小值 max(): 返回两个参数中的最大值 exp(): 返回自然数底数e的参数次方 log(): 返回参数的自然数底数的对数值 pow(): 返回第一个参数的第二个参数次方 sqrt(): 求参数的算术平方根 sin(): 求指定double类型参数的正弦值 cos(): 求指定double类型参数的余弦值 tan(): 求指定double类型参数的正切值 random(): 返回一个随机数
Java Character类
使用字符时,我们通常使用的是内置数据类型cahr 然后在实际开发中,我们经常会遇到需要使用对象,为了解决这个问题,Java语言为内置数据 类型char提供了包装类Character类. Character类提供了一系列方法来操纵字符,可以使用Character的构造方法创建一个Character类对象 Character ch = new Character("a"); Character类的成员方法 isLetter(): 是否是一个字母 isDigit(): 是否是一个数字字符 isWhitespace(): 是否一个空格 isUpperCase(): 是否是大写字母 isLowerCase(): 是否是小写字母 toUpperCase(): 指定字母的大写形式 toLowerCase(): 指定字母的小写形式 toString(): 返回字符的字符串形式,字符串的长度仅为1 ...请参考java.lang.Character API规范
Java String类
在Java中字符串属于对象, Java提供了String类来创建和操作字符串 创建字符串: String类有11种构造方法,这些方法提供不同的参数来初始化字符串 public class Main { public static void main(String[] args) { String greeting = "Hello world!"; char[] helloArray = {"h", "e", "l", "l", "o", "."}; String helloString = new String(helloArray); System.out.println(helloString); } } 注意: String类是不可改变的,所以一旦创建了String对象,那它的值就无法改变了. 如果需要对字符串做很多修改,那么应该选择使用StringBuffer & StringBuilder类 字符串长度 用于获取有关对象的信息的方法称为访问器方法 String类的一个访问器方法是length()方法,它返回字符串对象包含的字符数 连接字符串 String类提供了连接两个字符串的方法 String s3 = string1.concat(string2); //返回string1连接string2的新字符串 也可对字符串常量使用concat()方法: String s4 = "My name is".concat("Zara"); 更常用的是使用"+"操作符来连接字符串 String s5 = "Hello, " + " world" + "!"; 创建格式化字符串 String类使用静态方法format()返回一个String对象而不是PrintStream对象 String类的静态方法format()能用来创建可复用的格式化字符串,而不仅仅是用于一次打印输出 //例子: String fs; float floatVar = 9.8f; int intVar = 125; String stringVar = "Jimy"; fs = String.format("The value of the float variable is " + "%f, while the value of the integer" + "variable is %d, and the string " + "is %s", floatVar, intVar, stringVar); System.out.println(fs); //The value of the float variable is 9.800000, while the value of the integervariable is 125, and the string is Jimy String 方法 char charAt(int index): 返回指定索引处的 char 值 int compareTo(Object o): 把这个字符串和另一个对象比较 int compareTo(String anotherString): 按字典顺序比较两个字符串 int compareToIgnoreCase(String str): 按字典顺序比较两个字符串,不考虑大小写 String concat(String str): 将指定字符串连接到此字符串的结尾 boolean contentEquals(StringBuffer sb): 当且仅当字符串与指定的StringButter有相同顺序的字符时候返回真 static String copyValueOf(char[] data): 返回指定数组中表示该字符序列的 String boolean endsWith(String suffix): 测试此字符串是否以指定的后缀结束 boolean equals(Object anObject): 将此字符串与指定的对象比较 boolean equalsIgnoreCase(String anotherString): 将此 String 与另一个 String 比较,不考虑大小写 byte[] getBytes(): 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中 void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin): 将字符从此字符串复制到目标字符数组 int hashCode(): 返回此字符串的哈希码 int indexOf(int ch): 返回指定字符在此字符串中第一次出现处的索引 int lastIndexOf(int ch): 返回指定字符在此字符串中最后一次出现处的索引 boolean matches(String regex): 告知此字符串是否匹配给定的正则表达式 boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len): 测试两个字符串区域是否相等 String[] split(String regex): 根据给定正则表达式的匹配拆分此字符串 boolean startsWith(String prefix): 测试此字符串是否以指定的前缀开始 String substring(int beginIndex): 返回一个新的字符串,它是此字符串的一个子字符串 char[] toCharArray(): 将此字符串转换为一个新的字符数组 String toLowerCase(): 使用默认语言环境的规则将此 String 中的所有字符都转换为小写 String toUpperCase(): 使用默认语言环境的规则将此 String 中的所有字符都转换为大写 String trim(): 返回字符串的副本,忽略前导空白和尾部空白
Java StringBuffer和StringBuilder类
对字符串进行修改的时候,需要使用StringBuffer和StringBuilder类 和String类不同的是,StringBuffer和StringBuilder类的对象能够被多次的修改,且不产生新的未使用对象 StringBuffer和StringBuilder类之间的最大不同在于StringBuilder的方法不是线程安全的(不能同步访问) 由于StringBuilder相较于StringBuffer有速度优势,大多数情况下建议使用StringBuilder类. 然而在应用程序要求线程安全的情况下,则必须使用StringBuffer类 //例子 public class Main { public static void main(String[] args) { StringBuffer sBuffer = new StringBuffer("test"); sBuffer.append(" String Buffer"); System.out.println(sBuffer); //test String Buffer } } StringBuffer 方法 public StringBuffer append(String s): 将指定的字符串追加到此字符序列 public StringBuffer reverse(): 将此字符序列用其反转形式取代 public delete(int start, int end): 移除此序列的子字符串中的字符 public insert(int offset, int i): 将 int 参数的字符串表示形式插入此序列中 replace(int start, int end, String str): 使用给定 String 中的字符替换此序列的子字符串中的字符 ...
Java数组
用来存储固定大小的同类型元素 double[] myList; //首选的声明写法 myList = new double[1024]; //创建数组 数组作为函数的参数 数组可以作为参数传递给方法 数组作为函数的返回值 public class Main { public static void printArray(double[] array){ for(int i = 0;i < array.length;i++){ System.out.println(array[i] + " "); } } public static double[] reverse(double[] list){ double[] result = new double[list.length]; for(int i = 0, j = result.length - 1; i < list.length; i++, j--){ result[j] = list[i]; } return result; } public static void main(String[] args) { StringBuffer sBuffer = new StringBuffer("test"); sBuffer.append(" String Buffer"); System.out.println(sBuffer); //test String Buffer double[] myList = {1.9, 2.9, 3.4, 3.5}; //打印所有数组元素 for(int i = 0; i < myList.length; i++){ System.out.println(myList[i] + " "); } for(double ele:myList){ System.out.println(ele); } printArray(myList); //计算所有元素的总和 double total = 0; for(int i = 0;i < myList.length;i++){ total += myList[i]; } System.out.println("Total is " + total); //查找最大元素 double max = myList[0]; for(int i = 1;i < myList.length; i++){ if(myList[i] > max){ max = myList[i]; } } System.out.println("Max is " + max); double[] reverse = reverse(myList); printArray(reverse); } } Arrays类 java.util.Arrays类能方便地操作数组,它提供的所有方法都是静态的. 1.给数组赋值: 通过fill方法 2.对数组排序: 通缩sort方法,按升序. 3.比较数组: 通过equals方法比较数组中元素值是否相等 4.查找数组元素: 通过binarySearch方法能对排序好的数组进行二分查找法操作 public static void fill(int[] a, int val) public static void sort(Object[] a) public static boolean equals(long[] a, long[] a2) public static int binarySearch(Object[] a, Object key)
Java日期时间
java.util包提供了Date类来封装当前的日期和时间,Date类提供两个构造函数来实例化Date对象 1.Date(): 使用当前日期和时间来初始化对象 2.Date(long millisec): 该参数从1970年一月一日起的微秒数 Date对象创建后,可调用下面的方法: boolean after(Date date): 若当调用此方法的Date对象在指定日期之后返回true,否则返回false boolean before(Date date): 若当调用此方法的Date对象在指定日期之前返回true,否则返回false Object clone(): 返回此对象的副本 int compareTo(Date date): 比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数 int compareTo(Object obj): 若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException boolean equals(Object date): 当调用此方法的Date对象和指定日期相等时候返回true,否则返回false long getTime(): 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数 int hashCode(): 返回此对象的哈希码值 void setTime(long time): 用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期 String toString(): 转换Date对象为String表示形式,并返回该字符串 使用SimpleDateFormat格式化日期 import java.text.SimpleDateFormat; import java.util.Date; //时间日期专题 public class Main { public static void main(String[] args) { //初始化 Date 对象 Date date = new Date(); //使用toString()函数显示日期时间 System.out.println(date.toString()); //Thu Jun 06 17:13:04 CST 2019 //使用SimpleDateFormat格式化日期 SimpleDateFormat ft = new SimpleDateFormat("E yyyy.MM.dd "at" hh:mm:ss a zzz"); System.out.println("Current Date: " + ft.format(date)); //Current Date: 周四 2019.06.06 at 05:17:07 下午 CST } } 使用printf格式化日期 import java.util.Date; public class DateDemo { public static void main(String args[]) { // 初始化 Date 对象 Date date = new Date(); // 使用toString()显示日期和时间 String str = String.format("Current Date/Time : %tc", date ); System.out.printf(str); } } /---------------------------------------/ import java.util.Date; public class DateDemo { public static void main(String args[]) { // 初始化 Date 对象 Date date = new Date(); // 使用toString()显示日期和时间 System.out.printf("%1$s %2$tB %2$td, %2$tY", "Due date:", date); } } DateFormat格式化编码 日期和时间转换字符 解析字符串为时间 SimpleDateFormat类有一些附加的方法,特别是parse(),它试图按照给定的SimpleDateFormat对象的格式化存储 来解析字符串 Java 休眠(sleep) 可以让程序休眠 Thread.sleep(5*60*10); 测量时间 long start = System.currentTimeMillis(); System.out.println(new Date() + " "); Thread.sleep(5*60*10); //休眠10秒,不准确 System.out.println(new Date() + " "); long end = System.currentTimeMillis(); long diff = end - start; System.out.println("Difference is :" + diff/1000); //秒 Calendar类 如何设置和获取日期数据的特定部分,比如小时,日,或者分钟? 使用Calendar类 Calendar类的功能要比Date类强大很多,而且实现方式上也比Date类要复杂一些 Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说时透明的 ,只需使用getInstance方法创建即可 Calendar c = Calendar.getInstance(); //默认是当前日期 GregorianCalendar类 Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现 import java.util.Calendar; import java.util.GregorianCalendar; public class Main { public static void main(String[] args){ String months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; int year; //初始化Gregorian 日历 //使用当前时间和日期 //默认为本地时间和时区 GregorianCalendar gcalendar = new GregorianCalendar(); //显示当前时间和日期的信息 System.out.print("Date: "); System.out.print(months[gcalendar.get(Calendar.MONTH)]); System.out.print(" "+ gcalendar.get(Calendar.DATE) + " "); System.out.println(year = gcalendar.get(Calendar.YEAR)); System.out.print("Time: "); System.out.print(gcalendar.get(Calendar.HOUR) + ":"); System.out.print(gcalendar.get(Calendar.MINUTE) + ":"); System.out.println(gcalendar.get(Calendar.SECOND)); //判断当前年份是否为润年 if(gcalendar.isLeapYear(year)){ System.out.println("当前年份是润年"); }else{ System.out.println("当前年份不是润年"); } } }
JAVA方法
方法是解决一类问题的步骤的有序组合 方法包含于类和对象中 方法在程序中被创建,在其它地方被引用 方法的定义: 修饰符 返回值类型 方法名(参数类型 参数名) ... 方法体 ... return 返回值 main方法是被JVM调用 重载的方法必须具有不同的参数列表,不能仅仅依据修饰符或返回类型的不同来重载方法 构造方法: 所有的类都有构造方法,因为JAVA自动提供了一个默认构造方法,它把所有成员初始化为0. 一旦你定义了自己的构造方法,默认构造方法就会失效 finalize()方法: JAVA允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,用来清除回收对象 例如:可以使用finalize()方法来确保一个对象打开的文件被关闭了. 在finalize()方法里,必须指定在对象销毁时候要执行的操作.
JAVA流、文件、IO
输入流:表示从一个源读取数据 输出流: 表示向一个目标写数据 读取控制台输入: JAVA的控制台输入由System.in完成 为了获得一个绑定到控制台的字符流,可以把System.in包装在BufferedReader对象中来创建一个字符流 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) BufferedReader对象创建后,我们可以使用read()方法从控制台读取一个字符,或者用readLine()方法来读取一个字符串 //读写文件,一个流被定义为一个数据序列,输入流用于从源读取数据,输出流用于向目标写数据 //Object---(OutputStream, InputStream) //OutputStream---(FilterOutputStream,FileOutputStream,ByteArrayOutputStream) //FilterOutputStream---(BufferedOutputStream, DataOutputStream, PrintStream) //InputStream---(ByteArrayInputStream,FileInputStream,FilterInputStream,StringBufferInputStream,SequenceInputStream) //FilterInputStream---(BufferedInputStream, DataInputStream, PushbackInputStream) //FileInputStream //该流用于从文件读取数据,用关键字new来创建对象 import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; public class Main { public static void main(String[] args) { try{ //创建输入流对象来读取文件 FileInputStream f = new FileInputStream("C:Usersjasmintungmeijumain.cpp"); File ff = new File("C:Usersjasmintungmeijumain.cpp"); //也可使用一个文件对象来创建一个输入输出流对象来读取文件 InputStream fs = new FileInputStream(ff); }catch(FileNotFoundException ex) { System.out.println(ex); } } } 创建了InputStream对象,就可以使用下面方法来读取流或进行其它的操作 1:public void close() throws IOException{} 关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。 2:protected void finalize()throws IOException {} 这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常 3:public int read(int r)throws IOException{} 这个方法从InputStream对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1 4:public int read(byte[] r) throws IOException{} 这个方法从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1 5:public int available() throws IOException{} 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数。返回一个整数值 //FileOutputStream 该类用来创建一个文件并向文件中写数据 //FileReader,FileWriter类 //JAVA中的目录 创建目录: mkdir(),mkdirs() //读取目录: 一个目录其实就是一个File对象,它包含其它文件或文件夹 如果创建一个File对象并且它是一个目录,那么调用isDirectory()方法会返回true 可通过调用该对象上的list()方法,来提取它包含的文件和文件夹的列表 import java.io.File; public class DirList { public static void main(String args[]) { String dirname = "/tmp"; File f1 = new File(dirname); if (f1.isDirectory()) { System.out.println( "Directory of " + dirname); String s[] = f1.list(); for (int i=0; i < s.length; i++) { File f = new File(dirname + "/" + s[i]); if (f.isDirectory()) { System.out.println(s[i] + " is a directory"); } else { System.out.println(s[i] + " is a file"); } } } else { System.out.println(dirname + " is not a directory"); } } }
JAVA异常处理
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候可以避免 异常发生的原因有很多,通常包含一下几大类: 1.用户输入了非法数据 2.要打开的文件不存在 3.网络通信时连接中断,或者JVM内存溢出 要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常: 检查性异常: 最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的 Exception类的层次: 所有的异常类都是从java.lang.Exception类继承的子类 Exception类是Throwable类的子类. 除了Exception类外,Throwable还有一个子类Error. 在Java内置类中,有大部分常用检查性和非检查性异常 Java 语言定义了一些异常类在java.lang标准包中 由于java.lang包是默认加载到所有的Java程序的,所以大部分从运行时异常类继承而来的异常都可以直接使用 捕获异常: 使用try和catch关键字可以捕获异常. 多重捕获块 一个try代码块后面跟随多个catch代码块的情况叫多重捕获 throws/throw关键字 如果一个方法没有捕获一个检查性异常,那么该方法必须使用throws关键字类声明 throws关键字放在方法签名的尾部 import java.io.*; public class className { public void withdraw(double amount) throws RemoteException, InsufficientFundsException { // Method implementation } //Remainder of class definition } finally关键字 finally关键字用来创建在try代码块后面执行的代码块 无论是否发生异常,finally代码块中的代码总会被执行 在finally代码块中,可以运行清理类型等收尾善后性质的语句 finally代码块出现在catch代码块最后 try{ // 程序代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }finally{ // 程序代码 } 声明自定义异常 在java中可以自定义异常 注意: 1.所有异常都必须是Throwable的子类 2.如果希望写一个检查性异常类,则需要继承Exception类 3.如果想写一个运行时异常,那么需要继承RuntimeException类 例如: class MyException extends Exception{ // } 一个异常类和其它任何类一样,包含有变量和方法 如何使用自定义的异常类: // 文件名InsufficientFundsException.java import java.io.*; public class InsufficientFundsException extends Exception { private double amount; public InsufficientFundsException(double amount) { this.amount = amount; } public double getAmount() { return amount; } } // 文件名称 CheckingAccount.java import java.io.*; public class CheckingAccount { private double balance; private int number; public CheckingAccount(int number) { this.number = number; } public void deposit(double amount) { balance += amount; } public void withdraw(double amount) throws InsufficientFundsException { if(amount <= balance) { balance -= amount; } else { double needs = amount - balance; throw new InsufficientFundsException(needs); } } public double getBalance() { return balance; } public int getNumber() { return number; } } //文件名称 BankDemo.java public class BankDemo { public static void main(String [] args) { CheckingAccount c = new CheckingAccount(101); System.out.println("Depositing $500..."); c.deposit(500.00); try { System.out.println(" Withdrawing $100..."); c.withdraw(100.00); System.out.println(" Withdrawing $600..."); c.withdraw(600.00); }catch(InsufficientFundsException e) { System.out.println("Sorry, but you are short $" + e.getAmount()); e.printStackTrace(); } } } 通用异常 在java中定义了两种类型的异常和错误 1.JVM异常: 由JVM抛出的异常或错误.如:NullPointerException类, ArrayIndexOutOfBoundsException类,ClassCastException类 2.程序级异常: 由程序或者API程序抛出的异常 例如IllegalArgumentException类,IllegalStateException类
JAVA ByteArrayInputStream类
字节数组输入流在内存中创建一个字节数组缓冲区,从输入流读取的数据保存在该字节数组缓冲区. 用法: ByteArrayInputStream bArray = new ByteArrayInputStream(byte[] a); ByteArrayInputStream bArray = new ByteArrayInputStream(byte[] a, int off, int len); 成功创建字节数组流对象后,可用以下方法对流进行读操作或其它操作: 1.public int read(): 从此输入流中读取下一个数据字节 2.public int read(byte[] r, int off, int len): 将最多 len 个数据字节从此输入流读入字节数组 3.public int available(): 返回可不发生阻塞地从此输入流读取的字节数 4.public void mark(int read): 设置流中的当前标记位置 5.public long skip(long n): 从此输入流中跳过 n 个输入字节 例子: import java.io.*; public class ByteStreamTest { public static void main(String args[])throws IOException { ByteArrayOutputStream bOutput = new ByteArrayOutputStream(12); while( bOutput.size()!= 10 ) { // 获取用户输入值 bOutput.write(System.in.read()); } byte b [] = bOutput.toByteArray(); System.out.println("Print the content"); for(int x= 0 ; x < b.length; x++) { // 打印字符 System.out.print((char)b[x] + " "); } System.out.println(" "); int c; ByteArrayInputStream bInput = new ByteArrayInputStream(b); System.out.println("Converting characters to Upper case " ); for(int y = 0 ; y < 1; y++ ) { while(( c= bInput.read())!= -1) { System.out.println(Character.toUpperCase((char)c)); } bInput.reset(); } } }
JAVA DataInputStream类
数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本JAVA数据类型 用法: DataInputStream dis = DataInputStream(InputStream in); 方法: 1.public final int read(byte[] r, int off, int len)throws IOException 从所包含的输入流中将 len 个字节读入一个字节数组中。如果len为-1,则返回已读字节数 2.Public final int read(byte [] b)throws IOException 从所包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组 b 中 3.public final Boolean readBooolean()throws IOException, public final byte readByte()throws IOException, public final short readShort()throws IOException public final Int readInt()throws IOException 从输入流中读取字节,返回输入流中两个字节作为对应的基本数据类型返回值 4.public String readLine() throws IOException 从输入流中读取下一文本行 例子: DataInputStream和DataOutputStream的使用,该例从文本文件test.txt中读取5行,并转换成大写字母,最后保存在另一个文件test1.txt中 import java.io.*; public class Test{ public static void main(String args[])throws IOException{ DataInputStream d = new DataInputStream(new FileInputStream("test.txt")); DataOutputStream out = new DataOutputStream(new FileOutputStream("test1.txt")); String count; while((count = d.readLine()) != null){ String u = count.toUpperCase(); System.out.println(u); out.writeBytes(u + " ,"); } d.close(); out.close(); } }
JAVA ByteArrayOutputStream 类
字节数组输出流在内存中创建一个字节数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中 用法: OutputStream bOut = new ByteArrayOutputStream(); OutputStream bOut = new ByteArrayOutputStream(int a) 方法: 1.public void reset() 将此字节数组输出流的 count 字段重置为零,从而丢弃输出流中目前已累积的所有数据输出 2.public byte[] toByteArray() 创建一个新分配的字节数组。数组的大小和当前输出流的大小,内容是当前输出流的拷贝 3.public String toString() 将缓冲区的内容转换为字符串,根据平台的默认字符编码将字节转换成字符 4.public void write(int w) 将指定的字节写入此字节数组输出流 5.public void write(byte []b, int of, int len) 将指定字节数组中从偏移量 off 开始的 len 个字节写入此字节数组输出流 6.public void writeTo(OutputStream outSt) 将此字节数组输出流的全部内容写入到指定的输出流参数中
JAVA DataoutputStream 类
数据输出流允许应用程序以与机器无关方式将Java基本数据类型写到底层输出流 用法: DataOutputStream out = DataOutputStream(OutputStream out); 方法: 1.public final void write(byte[] w, int off, int len)throws IOException 将指定字节数组中从偏移量 off 开始的 len 个字节写入此字节数组输出流 2.Public final int write(byte [] b)throws IOException 将指定的字节写入此字节数组输出流 3.public final void writeBooolean()throws IOException, public final void writeByte()throws IOException, public final void writeShort()throws IOException, public final void writeInt()throws IOException 这些方法将指定的基本数据类型以字节的方式写入到输出流 4.Public void flush()throws IOException 刷新此输出流并强制写出所有缓冲的输出字节 5.public final void writeBytes(String s) throws IOException 将字符串以字节序列写入到底层的输出流,字符串中每个字符都按顺序写入,并丢弃其高八位
JAVA File类
JAVA文件类以抽象的方式代表文件名和目录路径名.该类主要用于文件和目录的创建,文件的查找和文件的删除等 File对象代表磁盘中实际存在的文件和目录 用法: File(File parent, String child); File(String pathname); File(String parent, String child); File(URI uri); 方法: 1 public String getName() 返回由此抽象路径名表示的文件或目录的名称。 2 public String getParent()、 返回此抽象路径名的父路径名的路径名字符串,如果此路径名没有指定父目录,则返回 null。 3 public File getParentFile() 返回此抽象路径名的父路径名的抽象路径名,如果此路径名没有指定父目录,则返回 null。 4 public String getPath() 将此抽象路径名转换为一个路径名字符串。 5 public boolean isAbsolute() 测试此抽象路径名是否为绝对路径名。 6 public String getAbsolutePath() 返回抽象路径名的绝对路径名字符串。 7 public boolean canRead() 测试应用程序是否可以读取此抽象路径名表示的文件。 8 public boolean canWrite() 测试应用程序是否可以修改此抽象路径名表示的文件。 9 public boolean exists() 测试此抽象路径名表示的文件或目录是否存在。 10 public boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。 11 public boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。 12 public long lastModified() 返回此抽象路径名表示的文件最后一次被修改的时间。 13 public long length() 返回由此抽象路径名表示的文件的长度。 14 public boolean createNewFile() throws IOException 当且仅当不存在具有此抽象路径名指定的名称的文件时,原子地创建由此抽象路径名指定的一个新的空文件。 15 public boolean delete() 删除此抽象路径名表示的文件或目录。 16 public void deleteOnExit() 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。 17 public String[] list() 返回由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组。 18 public String[] list(FilenameFilter filter) 返回由包含在目录中的文件和目录的名称所组成的字符串数组,这一目录是通过满足指定过滤器的抽象路径名来表示的。 19 public File[] listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件。 20 public File[] listFiles(FileFilter filter) 返回表示此抽象路径名所表示目录中的文件和目录的抽象路径名数组,这些路径名满足特定过滤器。 21 public boolean mkdir() 创建此抽象路径名指定的目录。 22 public boolean mkdirs() 创建此抽象路径名指定的目录,包括创建必需但不存在的父目录。 23 public boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。 24 public boolean setLastModified(long time) 设置由此抽象路径名所指定的文件或目录的最后一次修改时间。 25 public boolean setReadOnly() 标记此抽象路径名指定的文件或目录,以便只可对其进行读操作。 26 public static File createTempFile(String prefix, String suffix, File directory) throws IOException 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。 27 public static File createTempFile(String prefix, String suffix) throws IOException 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。 28 public int compareTo(File pathname) 按字母顺序比较两个抽象路径名。 29 public int compareTo(Object o) 按字母顺序比较抽象路径名与给定对象。 30 public boolean equals(Object obj) 测试此抽象路径名与给定对象是否相等。 31 public String toString() 返回此抽象路径名的路径名字符串 例子: import java.io.File; public class DirList { public static void main(String args[]) { String dirname = "/java"; File f1 = new File(dirname); if (f1.isDirectory()) { System.out.println( "Directory of " + dirname); String s[] = f1.list(); for (int i=0; i < s.length; i++) { File f = new File(dirname + "/" + s[i]); if (f.isDirectory()) { System.out.println(s[i] + " is a directory"); } else { System.out.println(s[i] + " is a file"); } } } else { System.out.println(dirname + " is not a directory"); } } }
JAVA FileReader类
FileReader类从InputStreamReader类继承而来,该类按字符读取流中数据. 用法: FileReader(File file); FileReader(FileDescriptor fd); FileReader(String fileName; 方法: 1 public int read() throws IOException 读取单个字符,返回一个int型变量代表读取到的字符 2 public int read(char [] c, int offset, int len) 读取字符到c数组,返回读取到字符的个数 例子: import java.io.*; public class FileRead{ public static void main(String args[])throws IOException{ File file = new File("Hello1.txt"); // 创建文件 file.createNewFile(); // creates a FileWriter Object FileWriter writer = new FileWriter(file); // 向文件写入内容 writer.write("This is an example "); writer.flush(); writer.close(); // 创建 FileReader 对象 FileReader fr = new FileReader(file); char [] a = new char[50]; fr.read(a); // 读取数组中的内容 for(char c : a) System.out.print(c); // 一个一个打印字符 fr.close(); } }
JAVA FileWriter类
FileWriter类从OutputStreamReader类继承而来。该类按字符向流中写入数据 用法: FileWriter(File file); FileWriter(File file, boolean append); FileWriter(FileDescriptor fd); FileWriter(String fileName, boolean append); 方法: 1 public void write(int c) throws IOException 写入单个字符c。 2 public void write(char [] c, int offset, int len) 写入字符数组中开始为offset长度为len的某一部分。 3 public void write(String s, int offset, int len) 写入字符串中开始为offset长度为len的某一部分。
Java 继承
JAVA中,类的继承是单一继承,一个子类只能拥有一个父类 继承中最常使用的两个关键字: extends 和 implements 这两个关键字的使用决定了一个对象和另一个对象是否是IS-A(是一个)关系 通过使用这两个关键字,我们能实现一个对象获取另一个对象的属性 所有JAVA的类均是由java.lang.Object类继承而来的,所以Object是所有类的祖先类, 除了Object外,所有类必须有一个父类 // A.java public class A { private int i; protected int j; public void func() { } } // B.java public class B extends A { } B由A继承而来的, B是A的子类. 而A是Object的子类, 这里可以不显示地声明 作为子类,B的实例拥有A所有的成员变量,但对于 private 的成员变量B却没有访问权限,这保障了A的封装性 什么是IS-A关系? 一个对象是另一个对象的一个分类 public class Animal{ } public class Mammal extends Animal{ } public class Reptile extends Animal{ } public class Dog extends Mammal{ } 分析以上示例中的IS-A关系,如下: Mammal IS-A Animal Reptile IS-A Animal Dog IS-A Mammal 因此 : Dog IS-A Animal 通过使用关键字 extends,子类可以继承父类的除private属性外所有的属性. 我们通过使用 instanceof 操作符,能够确定Mammal IS-A Animal(返回true or false) public class Dog extends Mammal{ public static void main(String args[]){ Animal a = new Animal(); Mammal m = new Mammal(); Dog d = new Dog(); System.out.println(m instanceof Animal); //true System.out.println(d instanceof Mammal); //true System.out.println(d instanceof Animal); //true } } implements 关键字 使用在类继承接口的情况下.这种情况下不能使用extends HAS-A 关系 代表类和它的成员之间的从属关系.有助于代码的重用和减少代码的错误 例子: public class Vehicle{} public class Speed{} public class Van extends Vehicle{ private Speed sp; } Van类和Speed类是HAS-A关系(Van有一个Speed),这样就不用将Speed类的全部代码粘贴到Van类中了 并且Speed类也可以重复利用于多个应用程序 JAVA只支持单继承(继承基本类和抽象类),但是我们可以用接口来实现(多继承接口来实现) public class Apple extends Fruit implements Fruit1, Fruit2{ } 一般我们继承基本类和抽象类用 extends 关键字,实现接口类的继承用 implements 关键字
JAVA重写Override与重载Overload
重写是子类对父类的允许访问的方法的实现过程进行重新编写,返回值和形参不能改变 重写的好处在于子类可以根据需求,定义特定于自己的行为 也就是说子类能够根据需要实现父类的方法 例子: class Animal{ public void move(){ System.out.println("动物可以移动"); } } class Dog extends Animal{ public void move(){ System.out.println("dog can run and walk"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); Animal b = new Dog(); //Dog对象 a.move(); //执行 Animal 类的方法 b.moev(); //执行 Dog 类的方法 } } 在上面的例子中可以看到,尽管b属于Animal类型,但是它运行的是Dog类的move方法。 这是由于在编译阶段,只是检查参数的引用类型。 然而在运行时,Java虚拟机(JVM)指定对象的类型并且运行该对象的方法。 因此在上面的例子中,之所以能编译成功,是因为Animal类中存在move方法,然而运行时,运行的是特定对象的方法 思考例子: class Animal{ public void move(){ System.out.println("动物可以移动"); } } class Dog extends Animal{ public void move(){ System.out.println("狗可以跑和走"); } public void bark(){ System.out.println("狗可以吠叫"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal 对象 Animal b = new Dog(); // Dog 对象 a.move();// 执行 Animal 类的方法 b.move();//执行 Dog 类的方法 b.bark(); } } 运行结果: TestDog.java:30: cannot find symbol symbol : method bark() location: class Animal b.bark(); 该程序将抛出一个编译错误,因为b的引用类型Animal没有bark方法 方写重写的规则 参数列表必须完全与被重写方法的相同; 返回类型必须完全与被重写方法的返回类型相同; 访问权限不能比父类中被重写的方法的访问权限更高。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。 父类的成员方法只能被它的子类重写。 声明为 final 的方法不能被重写。 声明为 static 的方法不能被重写,但是能够被再次声明。 如果一个方法不能被继承,那么该方法不能被重写。 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。 构造方法不能被重写。 如果不能继承一个方法,则不能重写这个方法 Super关键字的使用 当需要在子类中调用父类的被重写方法时,要使用super关键字 class Animal{ public void move(){ System.out.println("anmial can move"); } } class Dog extends Animall{ public void move(){ super.move(); //调用 super类的方法 System.out.println("dog can run and walk"); } } public class TestDog{ public static void main(String args[]){ Animal b = new Dog(); b.move(); } } 重载(Overload) 重载(overloading) 是在一个类里面, 方法名字相同, 而参数不同.返回类型呢?可以相同也可以不同 重载规则: 被重载的方法必须改变参数列表; 被重载的方法可以改变返回类型; 被重载的方法可以改变访问修饰符; 被重载的方法可以声明新的或更广的检查异常; 方法能够在同一个类中或者在一个子类中被重载 例子: public class Overloading { public int test(){ System.out.println("test1"); return 1; } public void test(int a){ System.out.println("test2"); } //以下两个参数类型顺序不同 public String test(int a,String s){ System.out.println("test3"); return "returntest3"; } public String test(String s,int a){ System.out.println("test4"); return "returntest4"; } public static void main(String[] args){ Overloading o = new Overloading(); System.out.println(o.test()); o.test(1); System.out.println(o.test(1,"test3")); System.out.println(o.test("test4",1)); } 重写与重载之间的区别 区别点 重载方法 重写方法 参数列表 必须修改 一定不能修改 返回类型 可以修改 一定不能修改 异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常 访问 可以修改 一定不能做更严格的限制(可以降低限制)
JAVA多态
多态,是同一个行为具有多个不同表现形式或形态的能力 比如我们说"宠物"这个对象,它就有很多不同的表达或实现,比如有小猫、小狗、蜥蜴等等。 那么我到宠物店说"请给我一只宠物",服务员给我小猫、小狗或者蜥蜴都可以,我们就说"宠物"这个对象就具备多态性 例子: public interface Vegetarian{} public class Animal{} public class Deer extends Animal implements Vegetarian{} 此时,Deer类具有多重继承,具有多态性 一个 Deer IS-A(是一个) Animal 一个 Deer IS-A(是一个) Vegetarian 一个 Deer IS-A(是一个) Deer 一个 Deer IS-A(是一个)Object 在JAVA中,所有的对象都具有多态性. 访问一个对象的唯一方法是: 通过引用型变量 引用型变量只能有一种类型,一旦被声明,引用型变量的类型就不能被改变了 引用型变量不仅能够被重置为其它对象,前提是这些对象没有被声明为final. 还可以引用和它类型相同的或者相兼容的对象.它可以声明为类类型或者接口类型 当我们将引用变量应用于Deer对象的引用时,下面的声明时合法的: Deer d = new Deer(); Animal a = d; Vegetarian v = d; Object o = d; 所有的引用型变量d,a,v,o都指向堆中相同的Deer对象 虚方法(可以理解为C++中的虚函数) 当子类对象调用重载的方法时,调用的是子类的方法,而不是父类中被重载的方法 想要调用父类中被重载的方法,必须使用关键字super 例子(仔细看): /* 文件名 : Employee.java */ public class Employee { private String name; private String address; private int number; public Employee(String name, String address, int number) { System.out.println("Constructing an Employee"); this.name = name; this.address = address; this.number = number; } public void mailCheck() { System.out.println("Mailing a check to " + this.name + " " + this.address); } public String toString() { return name + " " + address + " " + number; } public String getName() { return name; } public String getAddress() { return address; } public void setAddress(String newAddress) { address = newAddress; } public int getNumber() { return number; } } /* 文件名 : Salary.java */ public class Salary extends Employee { private double salary; //Annual salary public Salary(String name, String address, int number, double salary) { super(name, address, number); setSalary(salary); } public void mailCheck() { System.out.println("Within mailCheck of Salary class "); System.out.println("Mailing check to " + getName() + " with salary " + salary); } public double getSalary() { return salary; } public void setSalary(double newSalary) { if(newSalary >= 0.0) { salary = newSalary; } } public double computePay() { System.out.println("Computing salary pay for " + getName()); return salary/52; } } /* 文件名 : VirtualDemo.java */ public class VirtualDemo { public static void main(String [] args) { Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00); Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00); System.out.println("Call mailCheck using Salary reference --"); s.mailCheck(); System.out.println(" Call mailCheck using Employee reference--"); e.mailCheck(); } } 运行结果: Constructing an Employee Constructing an Employee Call mailCheck using Salary reference -- Within mailCheck of Salary class Mailing check to Mohd Mohtashim with salary 3600.0 Call mailCheck using Employee reference-- Within mailCheck of Salary class Mailing check to John Adams with salary 2400.0 例子中,我们实例化了两个Salary对象。一个使用Salary引用s,另一个使用Employee引用。 编译时,编译器检查到mailCheck()方法在Salary类中的声明。 在调用s.mailCheck()时,Java虚拟机(JVM)调用Salary类的mailCheck()方法。 因为e是Employee的引用,所以调用e的mailCheck()方法则有完全不同的结果。 当编译器检查e.mailCheck()方法时,编译器检查到Employee类中的mailCheck()方法。 在编译的时候,编译器使用Employee类中的mailCheck()方法验证该语句, 但是在运行的时候,Java虚拟机(JVM)调用的是Salary类中的mailCheck()方法。 该行为被称为虚拟方法调用,该方法被称为虚拟方法。 Java中所有的方法都能以这种方式表现,借此,重写的方法能在运行时调用,不管编译的时候源代码中引用变量是什么数据类型。
JAVA抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的, 如果一个类中没有包含足够的信息来描述一个具体的对象,这样的类就是抽象类 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量,成员方法和构造方法的访问方式和普通类一样 由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用.也就是因为这个原因,通常在设计阶段决定要不要设计抽象类 定义一个抽象类: /* 文件名 : Employee.java */ public abstract class Employee { private String name; private String address; private int number; public Employee(String name, String address, int number) { System.out.println("Constructing an Employee"); this.name = name; this.address = address; this.number = number; } public double computePay() { System.out.println("Inside Employee computePay"); return 0.0; } public void mailCheck() { System.out.println("Mailing a check to " + this.name + " " + this.address); } public String toString() { return name + " " + address + " " + number; } public String getName() { return name; } public String getAddress() { return address; } public void setAddress(String newAddress) { address = newAddress; } public int getNumber() { return number; } } 该Employee类没有什么不同,尽管该类是抽象类,但是它仍然有3个成员变量,7个成员方法和1个构造方法. 现在如果你尝试如下的例子: /* 文件名 : AbstractDemo.java */ public class AbstractDemo { public static vo
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/74947.html
摘要:排序算法和集合工具类排序算法和集合工具类。面试官总是问排序算法也不是在难为你,而是在考察你的编程功底。你首先要理解多线程不仅仅是和那么简单,整个并发包下面的工具都是在为多线程服务。 去年的这个时候楼主通过两个月的复习拿到了阿里巴巴的 offer,有一些运气,也有一些心得,借着跳槽季来临特此分享出来。简单梳理一下我的复习思路,同时也希望和大家一起交流讨论,一起学习,如果不对之处欢迎指正一...
摘要:写这篇总结,主要是记录下自己的学习经历,算是自己对知识的一个回顾。这个阶段学习的时候,要学会使用开发工具,比如或者来学习。这个阶段需要自己对自己有很强的自律去学习,不要看了一半就放弃了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 写这篇总结,主要是记录下自己的学习经历,算是自己对知识的一个回顾。也给想要学习 ...
摘要:写这篇总结,主要是记录下自己的学习经历,算是自己对知识的一个回顾。这个阶段学习的时候,要学会使用开发工具,比如或者来学习。这个阶段需要自己对自己有很强的自律去学习,不要看了一半就放弃了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 写这篇总结,主要是记录下自己的学习经历,算是自己对知识的一个回顾。也给想要学习 ...
摘要:写这篇总结,主要是记录下自己的学习经历,算是自己对知识的一个回顾。这个阶段学习的时候,要学会使用开发工具,比如或者来学习。这个阶段需要自己对自己有很强的自律去学习,不要看了一半就放弃了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 写这篇总结,主要是记录下自己的学习经历,算是自己对知识的一个回顾。也给想要学习 ...
阅读 1057·2021-11-12 10:34
阅读 984·2021-09-30 09:56
阅读 667·2019-08-30 15:54
阅读 2601·2019-08-30 11:14
阅读 1464·2019-08-29 16:44
阅读 3202·2019-08-29 16:35
阅读 2489·2019-08-29 16:22
阅读 2440·2019-08-29 15:39