运行第一个JAVA程序:
这里使用的开发环境是eclipse,新建一个java工程,然后可以看到src这个是存放java代码的地方,然后在src文件右击新建一个class(类),然后可以看到下图,同样和C语言一样java语言也有main函数,只是写法不一样,java语言的main函数写法如下,同时java里面的打印函数和C语言也不一样,java语言用的是System.out.println
,如下图进行打印,然后运行输出hello world
JAVA SE、EE、ME的区别:
-
Java SE(Java Platform,Standard Edition)。Java SE 以前称为 J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的 Java 应用程序。Java SE 包含了支持 Java Web 服务开发的类,并为 Java Platform,Enterprise Edition(Java EE)提供基础。总的来说: JAVA SE就是最标准的java语言,就和最基本的C语言一样,包含这个语言最基本的一些东西,在java里面包含一些最基本的继承、多态等等
-
Java EE(Java Platform,Enterprise Edition)。这个版本以前称为 J2EE。企业版本帮助开发和部署可移植、健壮、可伸缩且安全的服务器端 Java 应用程序。Java EE 是在 Java SE 的基础上构建的,它提供 Web 服务、组件模型、管理和通信 API,可以用来实现企业级的面向服务体系结构(service-oriented architecture,SOA)和 Web 2.0 应用程序。总的来说: JAVA EE相较于JAVA SE对了一些API(这些API是用来搞服务器用的,就相当于C语言面向linux的开发,也是多了一些API)
-
Java ME(Java Platform,Micro Edition)。这个版本以前称为 J2ME。Java ME 为在移动设备和嵌入式设备(比如手机、PDA、电视机顶盒和打印机)上运行的应用程序提供一个健壮且灵活的环境。Java ME 包括灵活的用户界面、健壮的安全模型、许多内置的网络协议以及对可以动态下载的连网和离线应用程序的丰富支持。基于 Java ME 规范的应用程序只需编写一次,就可以用于许多设备,而且可以利用每个设备的本机功能。总的来说: 相对于JAVA EE也是多了一些API面向于嵌入式设备。主要针对消费者电子设备,为嵌入式应用提供开发和运行环境,例如手机程序和PDA程序等等,可以理解为单片机的C语言。
-
相比较于SE,EE和ME提供针对指向不同的API。
JRE、JDK:
- JRE: 百度百科:Java运行环境(Java Runtime Environment,简称JRE)是一个软件,由太阳微系统所研发,JRE可以让计算机系统运行Java应用程序(Java Application)。JAVA程序之所以可以跨平台,就是有JRE,有了JRE,JAVA可以在windows、linux、手机环境下运行。只要在操作系统上装了JRE那么就可以运行java程序,所以java的移植性比较好。JRE的内部有一个Java虚拟机 (Java Virtual Machine,JVM)以及一些标准的类别函数库(Class Library)。
- JDK全称Java Development ToolKit,是Java语言开发工具包。JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime E nvirnment),一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。对于C语言来说,JDK有点像linux操作系统带的C语言的运行环境同时带了C库。没有JDK的话 无法编译 JAVA程序(指java源码的.java文件),如果想 只运行 jAVA程序(指class或jar或其他归档文件),要确已安装相应的JRE。
- JDK包含的基本组件有:javac(编译器,将源程序转成字节码,相当于C语言里面的gcc)、jar(打包工具,将相关的类文件打包成一个文件)、javadoc(文档生成器,从源码注释中提取文档,相当于man手册)、jdb(查错工具用来debug的)、java(运行编译后的java程序 .class 后缀的,.java 文件编译后生成 .class 文件)、appletviewer (小程序浏览器,一种执行HTML文件上的Java小程序的Java浏览器)、Javah(产生可以调用Java过程的C过程,或建立能被Java程序调用的C过程的头文件)、Javap (Java反汇编器,显示编译类文件中的可访问功能和数据,同时显示字节代码含义)、Jconsole ( Java进行系统调试和监控的工具)
java的基本数据类型:
- 总的来说和C语言没啥区别,只是输出时不用占位符,只需要用+拼接输出。
/*
以下代码相当于C语言的main函数,是程序的入口点int main(int argc,char** argv)//参数是参数的个数,和字符串数组(二级指针){return 0;}*/
public class Test {public static void main(String[] args) {//String[] args是字符串数组,就是一个参数System.out.println("hello1");System.out.println("hello2");//java里面的整形数int a=10;int b;b=10;int c=a+b;System.out.println("a="+a); System.out.println("a+b="+c);System.out.println("a="+a+" b="+b);//这里的+不带引号表示连接输出的内容System.out.println(a+"+"+b+"="+c);//这里带引号的加号是指直接将+输出,不带引号的还是起连接作用//java里面的浮点数/*float f=0.1; //环境写小数默认是double类型,所以不能赋值,要将f强制转换为double类型 */float f=(float)0.1;double d=0.02;System.out.println("f="+f);//因为该方法不存在占位符,所以直接将要输出的内容连进来就行了System.out.println("d="+d);}
}
java里面的选择语句:
- 基本上和C语言的没啥区别
public class Test {public static void main(String[] args) {int a=2;if(a>0){ //if语句和C语言基本一样System.out.println("a是正数");if(a==1){System.out.println("a是正数,并且等于1");}else{System.out.println("a是正数,并且不等于1");}}else{System.out.println("a是负数");}switch (a){//switch选择语句case 1:System.out.println("输出1");break;case 2:System.out.println("输出2");break;case 3:System.out.println("输出3");break;}}
}
java的循环控制语句:
- 和C语言一模一样,只是程序的入口函数不一样
public class Test {public static void main(String[] args) {int a=10;int b;for(b=1;b<10;b++){System.out.println("b="+b);}while(b>0){System.out.println("b="+b);b--;}}
}
java的数组:
- java里面的数组和C里面的数组在定义的时候稍微有点区别,但是在使用的时候都是通过数组下标来使用的,
public class Test {public static void main(String[] args) {/*int a[3];C语言数组定义但是在java里面不能这样定义*///int a[];//在java里面定义数组时不能体现数组的个数[]里面不能有数字int b[]={1,2,3};//这种定义方式在java和C里面都可以System.out.println(b[0]);//访问数组元素也是通过数组下标来访问的,也是从0开始的System.out.println(b[1]);System.out.println(b[2]);//在java里面定义一个空数组//int array[]=new int[3];//表示定义了一个有三个元素空间的空数组,array是数组名,int是数组的类型int[] array=new int[3];[]在数组名前面或者后面都可以int i;for(i=0;i<array.length;i++){//循环遍历数组,array.length就是求数组的长度System.out.println(array[i]);System.out.println(b[i]);}for(i=0;i<3;i++){array[i]=i;System.out.println(array[i]);}//数组的定义还可以这样写int[] array2=null;//arrary2[]/[]array2表示这是一个数组,数组的起始地址指向nullarray2=new int[3];//在句话再给数组做一个初始化给数组分配空间//数组的定义还可以这样写,即在数组初始化时给元素赋值int[] array3=new int[]{1,2,3};//等同于int[] array3={1,2,3}; }
}
java的函数:
- java里面的函数如果在定义时没有说明是static类型的函数那么,在函数调用的时候必须先创建对象然后通过对象访问类里面的方法,如果函数定义为static类型的,那么就可以像c语言那样调用函数。
public class Test {static void myprintf(){int b;//作用域也只是这个函数,和C语言一样System.out.println("第一个测试函数");}static void putAint(int a){System.out.println("函数传入的数字为"+a);}public static void main(String[] args) {int a=10;/*myprintf();//在main函数里面这样调用函数,前提是函数必须是static静态的putAint(a);*///如果不用以上调用方式,则可以用以下方式进行调用Test t=new Test();//创建类的对象,并为其开辟空间t.myprintf();t.putAint(a);//这种方式调用函数不用使函数定义为static类型的}
}
java实现计算器(+ - * /):
- 其实和C语言没啥区别,主要还是定义和使用的时候有些区别
public class Test {int add(int data1,int data2){return data1+data2;}int min(int data1,int data2){return data1-data2;}float div(int data1,int data2){return (float)data1/data2;}int mul(int data1,int data2){return data1*data2;}public static void main(String[] args) {//int[] score;//score=new int[10];//int[] score=new int[10];//查找最低分和最高分int score[]={67,60,31,40,50,88,99};int min;int max;int i;min=max=score[0];for(i=0;i<score.length;i++){if(max<=score[i]){max=score[i];}else if(min>score[i]){min=score[i];} }System.out.println("最高分为:"+max);System.out.println("最低分为:"+min);//实现计算器int data1=10;int data2=3;Test t=new Test();System.out.println("两数之和为:"+t.add(data1,data2));System.out.println("两数之积为:"+t.mul(data1, data2));System.out.println("两数之差为:"+t.min(data1, data2));System.out.println("两数相除为:"+t.div(data1, data2));}
}
java的输入类:
- java的输入类Scanner,然后创建对象,然后进行实例化(在实例化的时候要传入参数
System.in
可以理解为从键盘获取吧),就可以使用实例化对象里面的方法,根据输入的类型不同进而选择不同的方法。
import java.util.Scanner;
public class Test {public static void main(String[] args) {Scanner sc=new Scanner(System.in);//Scanner是类,sc是创建的对象(ctrl+shift+o)自动导包//new Scanner(System.in)是对sc进行实例化,这里还涉及到构造方法,后面将会学到int a;float f;double d;String str;System.out.println("请输入一个整数");a=sc.nextInt();//获取一个整数str=sc.nextLine();//吸收输入整数后的键盘的回车System.out.println("请输入一个字符串");str=sc.nextLine();//获取一个字符串System.out.println("请输入一个float小数");f=sc.nextFloat();//获取一个字符串System.out.println("请输入一个double小数");d=sc.nextDouble();//获取一个字符串System.out.println("得到整数:"+a);System.out.println("得到字符串:"+str);System.out.println("得到flaot小数:"+f);System.out.println("得到double小数:"+d);}
}
封装的概念:
将东西包在一起,然后以新的完整形式呈现出来,将方法和字段一起包装到一个单元中,单元以类的形式实现(类比C语言就是结构体,字段就是各种数据类型,方法就是函数指针),但是与C语言结构体不同的是,java的类有信息隐藏,隐藏对象的实现细节,不让外部直接访问到,就是外部看不到函数体。将数据和方法包装进类中,加上具体实现的隐藏(访问修饰符),共同被称作封装,其结果是一个同时带有特征和行为的数据类型。封装类: 定义类、定义其属性、方法的过程称为封装类。
- 下面是封装类的示例代码(可以类比于C语言的结构体):
/*struct Student{int age;char* name;double score;void (*introduce)(int age,int name,int score);void (*testFunc)();}
*/
class Student //封装类
{int age;String name;//java中没有char类型的变量,只有String类型的字符串double score;void introduce(){ //这个函数在用参数的时候如果使用类中的变量,则不用在函数定义的时候声明变量System.out.println("name="+name+"age="+age+"score="+score);}void testFunc(){System.out.println("testFunc"); }
}
public class Demo1 {public static void main(String[] args) {Student stu1=new Student(); //Student()括号内是用来传参数的,通过类实例化对象//类等于模板//类不能直接使用,不能直接访问变量,需要先实例化,申请一个访问空间/*上面那一行等同于C语言里面的struct Student *pp=malloc(sizeof(struct Student));先定义struct Student这个类型的变量再为其开辟空间,在java里面是一条语句完成的*/stu1.age=20;stu1.name="FHN";stu1.score=99;stu1.introduce();//这个函数没有参数,因为类内部有给字段赋值stu1.testFunc();}
}
java封装之访问修饰符:
信息隐藏是OOP最重要的功能之一,也是使用访问修饰符的原因。信息隐藏的原因包括:①对模块的任何实现细节所作的更改不会影响使用该模块的代码。②防止用户以外修改数据。③使模块易于维护和使用(就是电脑配件)。访问修饰符有: private
、protected
、public
、默认
。上面的代码没有修饰符,所以属性是默认属性。这些访问修饰符就是设置看能不能通过stu1.age=20
这样的形式访问变量。访问修饰符不仅可以修饰变量和方法还可以修饰类。
- 访问修饰符的访问权限:
- public:该类或非该类均可以访问
- private:只有该类可以访问(但是可以通过方法去间接地访问private修饰的变量)
- protected:该类及其子类的成员可以访问,同一个包中的类也可访问
- 默认:同一个包中的类可以访问
位置 | private | 默认 | protected | public |
---|---|---|---|---|
同一个类 | 是 | 是 | 是 | 是 |
同一个包内的类 | 否 | 是 | 是 | 是 |
不同包内的子类 | 否 | 否 | 是 | 是 |
不同包并且不是子类 | 否 | 否 | 否 | 是 |
- 属性封装的实现:修改属性的可见性来限制对属性的访问、为每个属性创建一对赋值的方法(setter)和取值的方法(getter)方法,用于公开对这些属性的访问接口,在setter和getter方法中,根据需要加入对属性操作限制。这样外部就可以通过这些方法来获取或者修改私有属性。
- 方法封装的目的:隐藏方法实现细节(方法体),向外部提供公开接口(方法头),以供安全调用,简化调用,方便维护。根据需要,可以私有化方法,以供内部使用(仅在类内部使用)。
UML类图:
Unified Modeling Language(UML)又称统一建模语言或标准建模语言,类的命名尽量应用领域中的术语,应明确、无歧义、以利于相互交流和理解。类的属性、操作中的可见性使用+、#、-
分别表示public、protected、private
构造方法:
- 类的构造方法的概念和作用:①构造方法负责对象的初始化工作,为对象的属性赋合适的初值。②创建对象时,其类的构造方法确保在用户操作对象之前,系统保证初始化的进行。
- 构造方法的语法规则:①构造方法与类名一致②没有返回类型③方式实现主要为字段赋初值。
- 构造方法的调用:构造方法的调用很特别,new操作符(实例化对象的时候,自动被调用),java系统保证每个类都有构造方法。 如果在类里面不写构造方法,它会自动的添加一个构造函数(无参构造方法)只是我们看不见而已,在一个类中可以有多个构造方法(函数的重载,参数列表一定要改),构造方法不能被重写
class Student //封装类
{int age;String name;//java中没有char类型的变量,只有String类型的字符串double score;
// Student(int newage,String newnme,double newscore) { //没有返回值是什么都不写而不是设置void的返回值
// System.out.println("构造方法被调用");
// age=newage;
// name=newnme;
// score=newscore;
// }Student() {//无参构造方法System.out.println("无参构造方法被调用");}Student(int newage,String newnme) { //在java中,方法是可重载的,在C中是不允许的System.out.println("构造方法一被调用");age=newage;name=newnme;}Student(int newage,double newscore) { System.out.println("构造方法二被调用");age=newage;score=newscore;}void introduce(){ //这个函数在用参数的时候如果使用类中的变量,则不用在函数定义的时候声明变量System.out.println("name="+name+"age="+age+"score="+score);}void testFunc(){System.out.println("testFunc"); }
}
public class Test {public static void main(String[] args) {Student stu1=new Student();Student stu3=new Student(18, "FHN");//在实例化的时候被调用,根据参数个数自动选择不同的构造方法Student stu2=new Student(18, 99);//在实例化的时候被调用,根据参数个数自动选择不同的构造方法stu3.introduce();}
}
- java中的重写和重载:
- 方法重载的概念: 同一个类中,同名不同参的方法称为重载方法,注意: 仅有返回值不同的方法不能称为重载。
- 多数程序设计语言要求为每个方法(函数)提供一个独一无二的方法名,不存在方法重载的概念,在java中,规定方法签名是解析方法的规则而不是方法名,为方法重载开创了条件,方法重载使得在一个类中,方法名相同而参数列表不同的方法可同时存在,代表相似的行为或功能。
- 例如:
System.out.print
这个函数就支持方法重载:
方法重写:
- 什么是方法重写? 方法重写是指子类可以根据需要对从父类继承来的方法进行改写,是多态机制的前奏。
- 方法重写的注意点: ① 重写方法必须和被重写的具有相同的方法名称、参数列表和返回值。 ② 重写方法不能比被重写方法有更严格的访问权限。③ 父类的私有方法,不能被重写。 ④ 在子类重写方法中继续调用父类的被重写方法可以通过
super.函数
名获取。
class Person{String name;String address;private void printInfo(){System.out.println("父类adress:"+address);}void printName(){System.out.println("父类name:"+name);}
}
class Student extends Person{int score;void printName()//对父类方法进行重写,重写方法不能比被重写方法有更严格的访问权限{super.printName();System.out.println("子类name:"+name);}void printInfo(){//父类的私有方法,不能被重写,在这里虽然和父类里面的方法名一样//但是这不是方法重写,可以理解为在子类里面定义的一个和父类方法名一样的方法吧,既不是重写也不是重载super.printName();System.out.println("子类adress:"+address);}
}
public class Main {public static void main(String[] args) {Person p=new Person();Student s=new Student();//当构造一个子类对象的时候一定会先调用父类的构造方法来初始化父类的字段s.name="子类" ;s.address="河北";s.printName();//优先调用子类的方法s.printInfo();}
}
- 函数重载发生在同一个类里面,函数重写发生在继承关系里面
This关键字的特点:
- 在类的方法中,使用This关键字代表的是调用此方法的对象的引用
- This可以看做是一个变量,他的值是当前对象的引用
- 使用This可以处理方法中的成员变量和形参同名的问题(使用比较多)
- 在方法内需要用到调用到该方法的对象时,就可以用This
- 在类的构造方法中可以调用This([参列表])来调用该类的指定构造方法(使用比较多)
class Student //封装类
{int age;String name;//java中没有char类型的变量,只有String类型的字符串double score;Student() {//无参构造方法System.out.println("无参构造方法被调用");}Student(int age,String name) { //在java中,方法是可重载的,在C中是不允许的System.out.println("构造方法一被调用");this.age=age;this.name=name;}Student(int age,String nme,double score) { //没有返回值是什么都不写而不是设置void的返回值//this();//在类的构造方法中可以调用This([参列表])来调用该类的指定构造方法//在这个构造方法中调用无参构造方法this(22,"NHF");//但是使用this构造方法只能调用一个,只能放在这个构造方法的第一条语句System.out.println("构造方法二被调用");this.age=age;this.name=nme;//this表示是可以处理方法中的成员变量和形参同名的问题this.score=score;//在变量前加一个this就表示是当前类中的变量}void testThis(){/*Student stutmp=null;System.out.println(stutmp.age);并没有为stutmp开辟空间这样访问这里面的值会出现错误*/Student stutmp=null;stutmp=this;//This可以看做是一个变量,他的值是当前对象的引用,就是当前对象的一个别名System.out.println(stutmp.age);System.out.println(this.name);//This关键字代表的是调用此方法的对象的引用}
}
public class Test {public static void main(String[] args) {Student stu1=new Student(18,"FHN",20);stu1.testThis();//This关键字在这里代表是调用此方法的对象的引用,也就是stu1的引用}
}
static关键字的特点:
- 用来修饰类的成员—修饰成员变量的称为类变量(静态变量)
- 修饰成员方法称之为类方法(静态方法)
- 当类被加载的时候就会被加载,优先于对象的存在
- 用来修饰语句—称之为静态代码,先于构造方法之前执行,只会执行一次,用来对静态成员做初始化
- 调用的时候可以直接通过
类名.成员
进行访问。 - static关键字的注意事项: ①静态方法只能访问外部静态成员。②静态方法中不能出现this关键字。因为this是指的是对象的引用,而静态方法是先于对象之前的,可以直接通过类来访问静态方法,不通过实例化对象来访问静态方法。
class Student //封装类
{int age;String name;//java中没有char类型的变量,只有String类型的字符串double score;static int data;//修饰类里面的变量(静态变量)Student(int age,String nme,double score) { //没有返回值是什么都不写而不是设置void的返回值System.out.println("构造方被调用");this.age=age;this.name=nme;//this表示是可以处理方法中的成员变量和形参同名的问题this.score=score;//在变量前加一个this就表示是当前类中的变量}void introduce(){ //这个函数在用参数的时候如果使用类中的变量,则不用在函数定义的时候声明变量System.out.println("name="+name);System.out.println("age="+age);System.out.println("score="+score);System.out.println("data="+data);}void testFunc(){System.out.println("testFunc"); }static{//这个是静态代码快,先于构造方法执行,不管实例化多少对象他只会执行一次,而构造方法会执行多次System.out.println("先于构造方法之前执行,只会执行一次,用来对静态成员做初始化");data=10000;//age=19;静态方法只能访问外部静态成员}
}
public class Test {public static void main(String[] args) {Student stu1=new Student(18,"FHN",20);Student.data=10;//静态变量可以直接通过类名来访问(也可以通过实例化后的对象来访问),其他成员变量必须先实例化然后再访问。//当类被加载的时候data就会被加载,优先于对象的存在,可以不依赖于对象来访问stu1.introduce();System.out.println("和为:"+Test.add(1, 2));Test tes1=new Test();System.out.println("差为:"+tes1.min(3,2));}static int add(int data1,int data2)//加上static就可以通过类名来直接访问类方法{return data1+data2;}int min(int data1,int data2)//不加static必须通过实例化对象来访问方法{return data1-data2;}
}
包(package):
打包的意义:
- 标准的java库是由一系列包组成的,包括
java.lang、java.util、java.net
等等 - 标准的java包就是层次型包结构,就如同硬盘上嵌套的子目录一样,我们可以使用嵌套层次来组织包
- java的包是为了更好的规划代码,防止命名冲突和混乱。所以java出现了打包机制
- 当把类组织起来放进一个包之内时,也就给包中的成员赋予了相互访问的权限,就可以拥有了该包内的程序代码
- 包访问权限把类聚集在一个包中这一做法提供了意义和理由。
- java开发人员可以编写属于自己的java包,为了保证包名唯一性,要求开发人员在定义自己的包时在名字前加上唯一的前缀。由于互联网的域名名称不会重复,所以推荐采用公司在互联网上的域名的倒置作为包的唯一前缀。
- 一个类可以使用同一个包中的所有类,一个类可以使用其他包中的所有公开类。怎么使用其他包中的公开类? ① 在每个类签名加上完整包名,例如:
java.until.Data today=new java.util.Date()
②更简洁更通用的方式:使用import语句来导包(eclipse ctrl+shift+o) import java.util.Date(导入特定类) Date today=new Date()
③可以import特定类,也可以导入整个包。通过在源代码文件的顶部(打包语句后)使用import语句实现import java.util.*
- 注意:包名后面的每一个点都代表一级文件,比如上图的包名
com.first.fhn
相应的会在工程文件下面的src
和bin
下面新建文件夹,然后再将包放在对应的位置。如下图所示:
总结: 这篇博客讲了封装的概念、UML类图、构造方法、this关键字、static关键字、方法重载、方法重写、包(packahe)