目录
一、程序书写tips
OOP特性:
(1)一切都是对象,
(2)程序就是一堆相互发送消息的对象
(3)每个对象都有独立的内部存储空间
(4)属性就是指变量,,方法就是指函数
编写 Java 程序时,应注意以下几点:
- 大小写敏感:Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的。
- 类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass。
- 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
- 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。
- 主方法入口:所有的 Java 程序由 public static void main(String []args) 方法开始执行。
java是一个强类型语言,变量在使用前必须定义
每一条语句以分号结尾
注释与C语言一样
Java使用Unicode编码,,支持汉字
当一个源文件中有多个类时, 只能有一个类用public修饰(主类), 源文件名必须是那个public 类的名字;如果没有public 类,源文件和其中任何一个 类名相同即可。
注:String args[] 与 String[] args 都可以执行,但推荐使用 String[] args,这样可以避免歧义和误读.
主类的一般书写形式
public class yan{
public static void main(String args[]){
exp();
}
}
文档注释符/** */ 用“/**”表示开始、用“*/”表示结束,包含在这部分中的注释可以通过javadoc命令 来自动生成API文档(html文档)
appletviewer.exe——模拟WWW浏览器运行Applet的应用程序,使用它调 试程序,不需要反复调用庞大的浏览器。 命令格式为: appletviewer 文件名.html
javap.exe 这是Java反汇编器,显示编译类文件中的可访问功能和数据,同时显示字节 代码含义。
jar.exe 这是Java打包工具,可将多个相关的类文件打包成单个JAR文件,用来发布 Java应用程序,双击该jar文件即可运行应用程序。
源文件中定义了几个类,编译结果就生成几个字节码文件。
Java applet 只有图形界面
Java application有图形界面和字符界面(cmd) 两种形式
标识符必须以字母、 _、$开头
(1)变量名、对象名、方法名、包名等 标识符全部采用小写字母;
如果标 识符由多个单词构成,则首字母小 写,其后单词的首字母大写,其余 字母小写,如:getAge。
(2)类名要求每个单词的首字母 大写 ,如:HelloWorldApp
(3)常量名为全大写,如果是由多 个单词构成,可以用下划线隔开, 如: WEEK_OF_MONTH
二、multi-sources处理
一个源文件中只能有一个public类
一个源文件可以有多个非public类
源文件的名称应该和public类的类名保持一致。例如:源文件中public类的类名是Employee,那么源文件应该命名为Employee.java。
如果一个类定义在某个包中,那么package语句应该在源文件的首行。如,package abc; abc是包名
如果源文件包含import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面。
import语句和package语句对源文件中定义的所有类都有效。
在同一源文件中,不能给不同的类不同的包声明。
多个源文件放在一个目录下,也就是Java的一个包(package),包中可以嵌套另一个包
书写package包时,也不能只写当前文件夹的名字,,要以src目录为基目录,通过圆点运算符向下延伸到当前文件所在的文件夹
package abc.asd;
src文件夹相当于是源文件存放的根目录
在源文件中import包时,以src目录为基目录,通过圆点运算符向下延伸到目标类,,注意是延申到类而非文件夹或文件
如果多个源文件处于同一个包,它们的类不需要import便可相互引用
如果多个源文件处于不同的包,它们之间必须要import才能引用,由于只有public类才能被import到不同包,所以建议一个文件只写一个类
可以用 包 .* 代表这个文件夹下所有的public类,,
如果多个类位于一个源文件,对于外包来说只能import到public的类,而这个文件的非public的类就无法在外包使用了
使用哪个类,就必须import哪个类,即便这几个类在一个文件中也不行,所以提倡一文件一类,以避免无法对外包import
例如类A和类B在一个文件中,其中A是public的,如果我想在外包用B,即便import A 也行不通,由于B不是public,没法被外包import
import bcd.asd.FreshJuice;
以上abc和bcd时src目录下的文件夹
源文件后缀名为.java
javac.exe编译.java文件生成.class文件,,
java.exe解释.class文件运行
每一个类都可以有自己的main函数
所谓main方法,就是程序执行的地方,程序只会执行main方法,在main方法中调用其他模块
主类中的main方法作为操作系统的入口函数,如下
主类的一般书写形式
public class yan{
public static void main(String args[]){
exp();
}
}
三、关键字
四、输入流和输出流
(1)输入语句
1.使用Scanner类:
(1)使用java.util包。 import java.util.*;
(2)构造Scanner类对象,它附属于标准输入流System.in。 Scanner s = new Scanner(System.in);
(3)常用的next()方法系列:
nextInt():输入整数
nextDouble():输入双精度数
next():输入字符串(以空格标志结束)。
nextLine():输入字符串 (可带空格)
import java.util.*;
public class DEMO_1 {
public static void main(String[] args){
Scanner s = new Scanner(System.in);
System.out.print("输入你的姓名:");
String name = s.nextLine();
System.out.print("输入你的年龄:");
int age = s.nextInt();
System.out.println("姓名:" + name + " 年龄:" + age );
s.close(); //若没有关闭Scanner对象将会出现警告
}
}
前缀0表示输入的是八进制,,,前缀0x表示输入的是16进制
(2)输出语句
System.out.println(1111);//换行打印
System.out.print(1111);//不换行打印
System.out.write(2222);//字节输出
System.out.printf("%+8.3f\n", 3.14);//按格式输出
System.out.println(); 是最常用的输出语句,它会把括号里的内容转换成字符串输出到输出窗口(控制台),并且换行,当输出的是一个基本数据类型时,会自动转换成字符串,如果输出的是一个对象,会自动调用对象的toString();方法,将返回值输出到控制台
System.out.print(); 与第一个很相似,区别就是上一个输出后会换行,而这个命令输出后并不换行。
System.out.printf(); 这个方法延续了C语言的输出方式,通过格式化文本和参数列表输出。
五、数据类型
(1)简单数据类型
字节型(1位byte)标准型(4位int) 短整型(2位short)
长整型(8位long)字符型(2位char) 布尔型(1个bit位boolean)
int a, b, c; // 声明三个int型整数:a、 b、c
int d = 3, e = 4, f = 5; // 声明三个整数并赋予初值
byte z = 22; // 声明并初始化 z
String s = "runoob"; // 声明并初始化字符串 s
String s = null //空串
double pi = 3.14159; // 声明了双精度浮点型变量 pi
char x = 'x'; // 声明变量 x 的值是字符 'x'。
在定义long类型时,要在数字后面加上L,,定义float类型时,要在后面加上f
java 语言为每一个内置数据类型提供了对应的包装类:
所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。
包装类有常量成员变量SIZE MAX_VALUE MIN_VALUE 可以直接通过类名打印具体信息
boolean型,,赋值false或ture
简单数据类型不会自动初始化,变量在初始化之前不能使用
在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似:
final double PI = 3.1415927;
(2)容器数据类型(引用类型)
- 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
- 对象、数组都是引用数据类型。
- 所有引用类型的默认值都是null。
- 一个引用变量可以用来引用任何与之兼容的类型。
- 例子:Site site = new Site("Runoob")。
数组(array) 类(class) 接口(interface)
数组对象有一个成员length,访问该成员可以获得数组元素的个数
容器类型(的元素)会自动初始化,见下:
(1)字符串
字符串之间的连接可以用+号,,,,,字符串与整型的链接也要用加号,,,此时把整型当成字符串,,,但并不会影响整型后续的使用
字符串本质上属于数组
字符串的创建:
String str=“ABCD”;
字符串常量和字符常量都可以包含任何Unicode字符。例如:
char a = '\u0001'; //16进制
String a = "\u0001"; //16进制
符号 | 字符含义 |
---|---|
\n | 换行 (0x0a) |
\r | 回车 (0x0d) |
\f | 换页符(0x0c) |
\b | 退格 (0x08) |
\0 | 空字符 (0x20) |
\s | 字符串 |
\t | 制表符 |
\" | 双引号 |
\' | 单引号 |
\\ | 反斜杠 |
\ddd | 八进制字符 (ddd) |
\uxxxx | 16进制Unicode字符 (xxxx) |
(2)一维数组
数组用于保存同类型变量
Java中数组的长度是固定的,即数组创建后,在内存中为数组分配了固定 大小的空间,在数组的使用中,这个空间的长度保持不变。
数组定义方法:
int[] numbers new int[4]; double[] averages = new double[20];
int[] scores = {87, 98, 69, 54, 65, 76, 87, 99};
(2)二维数组
二维数组:
int[][] a = new int[3][5];
int[][] a = { {1,2,3,4}, {1,2,3},}; //注意和C语言不同的是java二维数组不必给出列数
(3)枚举
枚举限制变量只能是预先设定好的值。使用枚举可以减少代码中的 bug。
class FreshJuice {
enum FreshJuiceSize{ SMALL, MEDIUM , LARGE }
FreshJuiceSize size;
}
public class FreshJuiceTest {
public static void main(String []args){
FreshJuice juice = new FreshJuice();
juice.size = FreshJuice.FreshJuiceSize.MEDIUM; //枚举类型必须用 类名.枚举变量.元素 来访问
}
}
(4)对象
对象也是一种数据类型,有自己的生存期和作用域,这一点和简单变量没什么区别
对象的类属性无论是简单变量还是容器变量都会自动初始化
ArrayList<String> notes = new ArrayList<String>();
ArrayList<String>是一个容器类,即存储对象的一个容器,其大小是动态的,与数组的定长不同,,,其作用是用来存放任意数量的对象,,其中ArrayList表示容器类型,,,<String>表示里面的元素类型
HashSet<String>与ArrayList<String>类似,但是前者表示的是一种集合,并不在意顺序,而且具有集合的互异性,即不会出现相同元素,若add了相同元素,则会把前一个删掉,以后一个为准
String[]是一个字符串数组类,,在Java里一切皆为类
对象数组的变量名管理的是素组中的每一个元素,每一个元素也可能是对象
(5)接口
接口就是一种抽象的类,顾名思义,用于对象之间的通信
(3)数据类型转换
不同类型的数据运算会先自动转换成更宽的类型,再进行运算
强制类型转换和C语言一样
数据类型判断使用:
关键字:A instanceof <基础数据类型包装类> //A是一个实例对象,判断A是不是尖括号里的包装类,返回boolean
String name = "James";
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
六、运算符
简单数据类型的赋值操作,新的变量是独立的
容器类型的赋值操作,仅仅是使新的变量引用了旧的变量,它们指向同一地址
• == 判断两个变量是否为同一个引用,是则为true,不同则为False。
• equals()方法则用于比较二者的内容是否相同,相同则为true, 不同则为False。
单目运算符 断言 赋值运算符 是从右向左的 其他的是从左向右
运算符优先级和C语言一样
>>:表示有符号移位
>>>表示无符号移位(C语言中没有)
^表示按位异或,,不存在逻辑异或
七、控制流
Java中有三种主要的循环结构:
- while 循环
- do…while 循环
- for 循环
条件 循环 分支 都是与C语言一样的(Java的switch case支持字符类型char和字符串类型String)
java 的for each的使用
String [] names ={"James", "Larry", "Tom", "Lacy"};
for( String name : names ) {
System.out.print( name );
System.out.print(",");
八、函数
对于函数内部的本地变量,它的生存期和作用域从进入函数开始,从离开函数消失
对于类的成员变量,它的生存期从对象的创建开始,至于什么时候消失由Java自动回收,程序员无需知道
/*这种结构在c/c++中是允许的,表示两个存储在不同位置上k,互不影响*/
/*但是在Java里不允许这种结构的出现,否则报错*/
{
int k;
{
int k;
}
}
九、面向对象基础
(1)类的组成
一个类可以包含以下类型变量:
- 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。其作用域被局限在方法之中,,局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
- 成员变量:成员变量是定义在类中,方法体之外的变量。每创建一个对象就会复制一份,每个对象的实例变量互不影响。成员变量可在类内部被访问。实例变量生命周期随着对象的创建而出现,,随着对象的消失而消失。
- 类变量:在成员变量的基础上用static修饰,,静态变量只有一份,属于类而不属于任何对象,可以通过对象名或类名来访问,通过对象名或类名都可以修改它的值,类变量生命周期最长,随着类的加载而出现,,随着类的消失而消失。
public class Variable{
static int allClicks=0; // 类变量
String str="hello world"; // 实例变量
public void method(){
int i =0; // 局部变量
}
}
public class Dog{
String breed;
int age;
String color;
void barking(){
}
void hungry(){
}
void sleeping(){
}
}
(2)类的定义
构造方法-----方法名与类名相同,不用写函数的返回类型.
class Student
{
String stuName; //成员变量会自动初始化
String stuClass; //成员变量会自动初始化
Student(String m,String s) //构造方法,可以有多个构造方法,创建对象时根据参数表自动选择用哪个
{
this.stuName=m; //this代表对象本身,Java里可省略不写,如果是静态方法则不能写this
this.stuClass=s;
}
void setClass(String sc ) //成员方法
{
stuClass=sc;
}
}
缺省构造:
在不定义构造方法时,系统会自动为该类生成一个默认的空构造方法, 也称为缺省构造方法。用缺省构造方法初始化对象时,系统用缺省值 初始化类对象的数据成员。 各数据类型的缺省值如下:
数值型:0
布尔型:false
字符型:’\0’ //表示空字符
类:null
当类中有构造函数时,创建对象时会先把实参传进形参,紧接着会初始化类的成员变量,之后再回到构造函数,,(创建的过程中不会访问成员方法)
一个类中可以有多个构造函数,只要它们的参数表不同,,,创建对象时会根据不同的实参,选择不同的构造函数,,这叫做重载
/*在Java的任何一个类中,只要有以下这个方法,在使用System.out.println()输出一个对象本身时,会输出以下这个方法返回的字符串,,但是要求这个方法不能改变任何结构*/
public String toString() //toString()方法
{
return ""+i ; //i是该方法所在类中的一个变量,在这里自动转化为字符串类型
}
(3)类的继承
- 在 Java 中,一个类可以由其他类派生。如果你要创建一个类,而且已经存在一个类具有你所需要的属性或方法,那么你可以将新创建的类继承该类。
- 利用继承的方法,可以重用已存在类的方法和属性,而不用重写这些代码。被继承的类称为超类(super class),派生类称为子类(subclass)。
- Java不支持广度多继承,但支持深度多继承
class 父类 {
}
class 子类 extends 父类 {
}
(1)继承的特性
-
子类拥有父类非 private 的属性、方法。
-
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
-
子类可以用自己的方式实现父类的方法。
(2)继承关键字
继承可以使用 extends 和 implements (实现)这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承Object(这个类在 java.lang 包中,所以不需要 import)祖先类
(3)implements关键字
使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)
public interface A {
public void eat();
public void sleep();
}
public interface B {
public void show();
}
public class C implements A,B {
}
(4)super 与 this 关键字
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指对象本身。
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
(5)final关键字
final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写
实例变量也可以被定义为 final,被定义为 final 的变量不能被修改。被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final
(6)构造器
- 子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。
- 如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表,且必须要放在第一行
- 如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。
- 在调用子类构造器时,会先执行父类构造器,再执行子类构造器
class SuperClass {
private int n;
SuperClass(){
System.out.println("SuperClass()");
}
SuperClass(int n) {
System.out.println("SuperClass(int n)");
this.n = n;
}
}
// SubClass 类继承
class SubClass extends SuperClass{
private int n;
SubClass(){ // 自动调用父类的无参数构造器
System.out.println("SubClass");
}
public SubClass(int n){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass(int n):"+n);
this.n = n;
}
}
// SubClass2 类继承
class SubClass2 extends SuperClass{
private int n;
SubClass2(){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass2");
}
public SubClass2(int n){ // 自动调用父类的无参数构造器
System.out.println("SubClass2(int n):"+n);
this.n = n;
}
}
public class TestSuperSub{
public static void main (String args[]){
System.out.println("------SubClass 类继承------");
SubClass sc1 = new SubClass();
SubClass sc2 = new SubClass(100);
System.out.println("------SubClass2 类继承------");
SubClass2 sc3 = new SubClass2();
SubClass2 sc4 = new SubClass2(200);
}
}
******输出****************************
------SubClass 类继承------
SuperClass()
SubClass
SuperClass(int n)
SubClass(int n):100
------SubClass2 类继承------
SuperClass(int n)
SubClass2
SuperClass()
SubClass2(int n):200
(6)override(重写,覆盖)
- 1、方法名、参数表、返回值相同或更小。
- 2、访问权限不变或更大
- 3、抛出异常数不变或更小
- 4、存在于父类和子类之间。
- 5、方法被定义为final不能被重写。
(7)overload(重载,过载)
- 1、参数类型、个数、顺序至少有一个不相同。
- 2、存在于父类和子类、同类中。
- 3, 调用时根据参数的不同自动选择用哪个方法
(8)重写与重载之间的区别
区别点 重载方法 重写方法 参数列表 必须修改 不变 返回类型 可以修改 子集 异常 可以修改 子集 访问 可以修改 超集
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
(4)Java抽象类
-
1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
-
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
-
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
-
4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
-
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
-
6. 抽象类的成员变量一般声明为private,子类中用super(参数)调用父类的构造方法(这与子类无法使用父类private变量不矛盾)
(5)内部类:
十、java的修饰符
十一、Java的封装(Encapsulation)
public class Person{
private String name;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
十二、接口
- 在 Java 中,接口可理解为对象间相互通信的协议。
- 接口本质上是一个纯抽象的类,,接口中所有的方法必须是抽象方法,,接口的所有变量都是 static 和 final 变量
- 接口不会有构造方法
- 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
- 接口里的变量都隐式声明为 public static final(并且只能是 public,用 private 或 protected修饰会报编译错误)
- 接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,用 private 或 protected修饰会报编译错误)
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口
- 类描述对象的属性和方法。接口则包含类要实现的方法。
- 一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类
- 接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
- JDK 1.8 以后,接口里可以有静态方法和方法体了。
(1)接口的定义:
public interface A {
public void eat();
public void sleep();
}
public interface B {
public void show();
}
public class C implements A,B {
}
(2)接口的实现:
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面
...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...
(3)接口的继承
一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
public interface Football extends Sports
{
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endOfQuarter(int quarter);
}
在Java中,类的广度多继承是不合法,但接口允许广度多继承:
public interface Hockey extends Sports, Event
(4)标记接口
没有任何方法和属性的接口被称为标记接口。标记接口主要用于以下两种目的:
- 建立一个公共的父接口
- 向一个类添加数据类型
(5)接口的修饰符缺省
当接口本身缺省修饰符时,会默认为default abstract而不是public abstract
当接口的变量和方法缺省修饰符时,变量隐式声明为 public static final,方法隐式声明为public abstract。
十三、包
(1)为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。
(2)同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
(3)通常,一个公司使用它互联网域名的颠倒形式来作为它的包名.例如:互联网域名是 runoob.com,所有的包名都以 com.runoob 开头。包名中的每一个部分对应一个子目录。
(4)类文件中可以包含任意数量的 import 声明。import 声明必须在包声明之后,类声明之前。
(5)编译后的.class文件的绝对路径设置在系统变量 CLASSPATH 中。编译器和 java 虚拟机通过将 package 名字加到 class path 后来构造 .class 文件的路径.例如:
\classes 是CLASSPATH,.java源文件的package的名字是 com.runoob.test,则编译器会把编译后的.class文件放到 \classes\com\runoob\test 中
(6)可以创建classpath环境变量:
Windows 平台(DOS 命令行下): C:\> set CLASSPATH=C:\users\jack\java\classes
(7)另一部分参考multi-sources
十四、常用的官方类库