目录
一、面向对象的基本概念
面向对象程序设计是当今主流的程序设计范型,它取代了之前的结构化和面向过程编程。
Java就是一个非常典型的面向对象的语言。
面向对象的程序是由对象组成的,每个对象都有自己的特定功能方法。
通过这些隐藏在对象内的方法相互组合最后完成程序的功能。
比如同样是实现一个简单的Web浏览器,
可能会需要大约2000个过程,这些过程可能需要对很多全局变量进行操作;
如果采取面向对象的方法,只需要大约100个类,每个类里面实现20个方法。
面向对象的方法容易调错,也可以帮助程序员对整体设计有着清晰的结构划分。
这就是面向对象的优势。
二、类与对象
如果说面向对象是一种思想和编程模式,那么类就是实现这种思想的具体操作。
类是构造对象的模板或者蓝图,我们可以理解为烤焙饼干的模具,
通过这些模具我们可以得到相同的很多饼干,不同的模具也会产生不同的饼干模型。
类一般的定义形式如下:
class 类名{
数据类型 属性名称;
...
返回值类型 方法名称(数据类型 参数名称1,...,数据类型 参数名称n){}
...
}
在做好类模具之后我们还是得不到饼干,如果要得到饼干则必须进行烤焙,
在通过模具烤焙饼干的过程我们称为类的实例化,将类实例化为一个对象,格式一般如下:
类名 对象名称=new 类名()
如果需要访问类中的属性和方法,可以通过下述格式进行访问:
对象名称.属性名称;
对象名称.方法名称();
在java中对象的声明有两种含义,
声明对象:Student stu1=null;
实例化对象:Student stu2=new Student();
第一个只是声明了对象,并没有在内存空间中指定某一块内存给该对象使用,所以不能直接对stu1进行使用,
第二个是在声明的同时对stu2进行了实例化,在内存空间中制指定了某一块地址给stu2。
在对方法进行调用时也有两种方式:
stu2.study();//通过对象调用方法
new Student().study();//通过匿名对象调用方法
三、构造方法
构造方法即类的初始化方法,在通过new语句给类进行实例化时就调用了这个方法。
一般构造方法有两种形式:
//无参数构造
public 类名(){}
//有参数构造
public 类名(数据类型 参数1,...,数据类型 参数2){
this.属性1=参数1;
...
this.属性n=参数n;
}
在写构造方法的时候需要有以下几点注意:
- 构造方法名称一定要和类名相同,并且不要写方法的返回值类型(包括void),也没有return语句
- 每一个类中都会有一个默认的无参数构造方法
- 构造方法不能用对象调用,在创建对象时系统会自动调用构造方法
- 如果在类中用户写了构造方法,那么默认的构造方法则失效,若仍想使用默认构造方法,则需要用户自己实现该默认构造方法
- 构造方法可以重载,即通过不同的参数列表调用不同的构造方法
- 构造方法中可以调用其他的构造方法,调用格式为代码第一句为this()或者this(构造参数列表),不能两者互相调用,要有出口
比如我们定义一个学生类,对类进行实例化并且通过有参和无参构造生成对象:
public class Main {
public static void main(String[] args){
Student stu1=new Student();
Student stu2=new Student(80);
stu1.PrintScore();
stu2.PrintScore();
}
}
class Student {
private int score;
public Student(){
this.score=60;
}
public Student(int sc){
this.score=sc;
}
public void PrintScore(){
System.out.println("Score:"+this.score);
}
}
下面是输出结果:
可以看到第一个学生使用的无参构造函数,分数默认为60,第二个学生用的有参构造函数,分数赋值了80。
其创建一个对象的步骤如下:
- Student.class加载进内存
- 声明一个Student类型引用stu1
- 在堆内存中创建对象
- 给对象中属性默认初始化值
- 属性进行显示初始化
- 构造方法进展,将对象中的属性赋值,构造方法弹栈
- 将对象的地址值赋值给stu1
四、static关键字
static关键字是沿用C++的概念,在java中static可以修饰常量、变量、方法。
4.1静态常量
静态常量是一个非常常见的方法,
静态常量定义之后可以直接使用类名+常量名来对该常量进行访问,
比如Math类中的PI的定义就是用的静态常量的方法:
public class Math{
...
public static final double PI=3.14159265358979323846;
...
}
我们可以直接通过Math.PI来访问使用的值。
如果去掉static关键字, 那么PI就只能通过类的一个对象访问,并且每个Math对象都有一个PI副本,
而包括static关键字的静态常量在内存中只有一个副本,当且仅当在类初次加载时被初始化,这样的好处是方便在没有创建对象时进行调用。
4.2静态变量
静态变量使用的不是很多,如果将变量定义为static类型,
那么每个类只能有一个这样的变量,所有实例化出来的对象都需要到静态区中访问该变量,
一个对象修改该变量的值会影响所有要访问该变量的对象。
其访问的形式与静态常量相同:类名.静态变量名,方便我们在没有创建对象时进行调用。
public class Main {
public static void main(String[] args){
System.out.println(Person.country);
}
}
class Person{
public static String country="China";
}
静态变量和普通的不加static关键字的成员变量主要有以下几点区别:
- 静态变量属于类,称为类变量,而成员变量属于对象,称为实例变量
- 静态变量存储于内存中方法区得静态区,而成员变量存储与内存中的堆内存
- 静态变量与类的生命周期相同,而成员变量与对象的声明周期相同
- 静态变量可以通过类名调用,也可以通过对象调用,而成员变量只能通过对象名调用
4.3静态方法
静态方法同样也是可以在没有创建对象时就可以进行调用。
需要注意的是在实现静态方法的时候不可以访问类中的非静态变量、非静态常量、非静态方法等。
可以认为在静态方法中没有this参数的方法(在一个非静态的方法中,this参数指示这个方法的隐式参数)。
比例Math的求幂次方法pow:Math.pow(x,a)
public class Main {
public static void main(String[] args){
Person.PrintCountry();
}
}
class Person{
public static String country="China";
public static void PrintCountry(){
System.out.println(country);
}
}
比如我们定义一个静态方法,访问静态变量country打印国籍信息。
有一点需要注意的是,如果一个类中的所有方法都是静态的,
那么需要写一个私有的构造方法,其目的是不让其他类创建该类的对象,直接用类名调用静态方法即可。
五、main方法
接下来我们分析一下java程序的入口main函数的格式:
public static void main(String[] args){
...
}
- public:因为主函数需要被jvm调用,所以这里设置public保证其访问权限足够大能被jvm顺利调用
- static:因为要被jvm调用,不用创建对象,所以加入关键字static可以直接通过类名访问
- void:jvm调用主方法是不需要给jvm返回值,所以这里设置为空void类型
- main:通用的主方法名称,不是关键字但是被jvm识别
- String[] args:主方法的参数列表,可以改为别的名字,这里是沿用以前接受键盘录入的参数名