|
JavaSE_Start
JavaSE-No.5——Java数组的定义与使用
JavaSE-No.6.1——Java的类和对象
面向对象程序三大特性:封装、继承、多态。何为封装呢?简单来说就是套壳屏蔽细节。
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互
比如:说我们平常使用手机,我们只需要知道,如何开机,如何使用。并不关心手机内部的核心部件,不需要知道主板的线路布局,不需要知道CPU是如何设计的。厂商在出厂时,在外部套上壳,将内部隐藏起来,让用户可以与手机交互即可。
封装的实现需要我们先了解访问修饰限定符
Java中提供了四种访问限定符:
#
public:在任何地方,都可以访问它修饰的成员或方法,或者类。
#
protected:在继承会学到。
#
dafault:指默认。在同一个包中进行访问。
例如: 此时的year前面什么都不加,就是默认权限。
#
private:私有的。只能在当前类中访问。
我们现在建一个Date类:
public class Date {
public int year;
public int month;
public int day;
public Date() {
}
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public void printDate() {
System.out.println(year+" "+month+" "+day+" ");
}
public static void main(String[] args) {
}
}
我们新建一个类TestDemo,在TestDemo中用Date类,因为是public
修饰的,我们可以看到没有报错。year,month,day也都可以访问。
这时我们把year改成private
修饰,year的访问权限就变小了。只能在当前类中访问。这时我们的TestDemo中报错了,无法访问year
。
此时我们对year进行了封装,类外就不能访问这个被封装的year。
我们来思考一个 问题 ,如果外部想要使用year,应该怎么办呢?
答:这时我们需要对这个year,提供一个公开的接口
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
这样我们就可以在TeatDemo
中使用我们的year。
我们每次都手写接口,十分的麻烦,这时我们可以借助idea
。
总结:封装就是对类的实现细节进行隐藏,提供公开的方法,供类的调用者进行使用。
为了更好的管理类,把多个类收集在一起成为一组,称为软件包。
在Java中也引入了包,包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
在idea中建包, # 注意 #
包名,规范是小写的。通常会用公司的域名的颠倒形式。
这里其实就是建了三个文件夹
我们在www
下建一个类TestDemo,我们可以看到和src
下的TestDemo互不影响,且出现了一行代码。
例如1: 我们这里使用Array.toString
,会导一个系统的包,Arrays其实就是人家写好的一个类。
Arrays
在哪里呢?
如果我们不导包,我们应该如何使用toString
呢?我们就需要这样做:
public static void main(String[] args) {
int[] array = {1,2,3,4,5};
System.out.println(java.util.Arrays.toString(array));
}
我们来思考一个 问题 ,util
下面有很多包,如果我们要同时使用多个,我们应该怎么写呢?
import java.util.*;//导入util下所有的包
例如2: 我们创建一个Date类,在utli
和sql
下面都有Date的包,如果我们这样写,是正确的吗?
为什么会报错?
站在编译器的角度下,util
和sql
下都有Date,不知道应该调用哪个Date
,我们必须指定他。
import java.util.*;
import java.sql.*;
public class TestDemo {
public static void main(String[] args) {
java.util.Date date1 = new java.util.Date();//不会报错
java.sql.Date date2 = new java.sql.Date(12);
}
}
静态导入
例如: 使用Math.pow
,导入一个静态的包。(我们一般不这么用)
import static java.lang.Math.*;
public class TestDemo {
public static void main(String[] args) {
double a = pow(2,2);
}
}
java.lang
:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
java.lang.reflflect
:java 反射编程包;
java.net
:进行网络编程开发包。
java.sql
:进行数据库开发的支持包。
java.util
:是java提供的工具程序包。(集合类等) 非常重要
java.io
:I/O编程开发包。
我们先建一个学生类,我们已知全部学生都是宝宝班的。
class Student {
public String name;
public double score;
public int age;
public String classes;//宝宝班
public Student(String name, double score, int age) {
this.name = name;
this.score = score;
this.age = age;
}
}
我们来new两个学生。
public class Test {
public static void main(String[] args) {
Student student1 = new Student("依古比古", 69.5,18);
Student student2 = new Student("唔西迪西", 79.0,19);
}
}
我们发现,两个学生是宝宝班的,并且都存了一次。 问题 :我们是否能只存一次呢?
这时我们就要用到static
。
public String name;
public double score;
public int age;
public static String classes = "宝宝班";//用static修饰
此时我们的classes
就不会存到对象里,而是被存到了方法区
。
在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
这时我们可以把成员变量分为:普通成员变量
和静态成员变量
(static修饰)。
我们继续上面的代码,如果我们现在使用student1
去访问classes
。使用student1.c并没有classes。
但如果我们自己敲上.classes
我们看他并没有报错,但我们通常不会这么用。
静态成员变量[又叫类变量]:不属于对象。 所以正确的访问方式是通过类名来访问(如上图绿色)。
静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。
静态成员变量特性 :
不属于某个具体的对象,是类的属性,所有对象共享
的,不存储在某个对象的空间中
既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名
访问
类变量存储在方法区
当中
生命周期伴随类
的一生(即:随类的加载而创建,随类的卸载而销毁)
此外我们话可以加一个final,且必须初始化。
我们来分别写一个普通的方法
和一个静态方法
(static修饰)
public void func1() {
System.out.println("这是一个普通方法");
}
public static void func2() {
System.out.println("这是一个静态方法 -> 类方法");
}
我们访问静态方法时,也用类名.方法
来使用。
Student.func2();
我们来思考一个问题 ,如果我们在static修饰的
func2
中想使用name
,这样写,可以使用吗?public static void func2() { System.out.println("这是一个静态方法 -> 类方法" + name); }
答:当然不能,name是依赖于对象的引用的。但是func2调用的时候没有生成对象,静态方法不依赖于对象,不能调用name。
我们再看一个问题 ,那我们是否能在
func1
中使用static修饰的classes
?public void func1() { System.out.println("这是一个普通方法"); classes = "花园班"; }
答:可以,因为func1依赖对象,classes不依赖对象,func1依赖的更多。
那么我们可以怎么访问name呢?可访问的方法:
public static void func2() {
Student student = new Student("依古比古", 69.5,18);
System.out.println("这是一个静态方法 -> 类方法" + student.name);
}
public static void func2(Student student) {
System.out.println("这是一个静态方法 -> 类方法" + student.name);
}
静态成员方法特性 :
不属于某个具体的对象,是类方法
可以通过对象调用,也可以通过类名.静态方法名(…)方式调用,更推荐使用后者
不能直接在静态方法中访问任何非静态成员变量
静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用
知识小拓展 |
在普通方法中,隐藏着一个this参数,但在静态方法和构造方法中没有。
# 注意 #
静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性
静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化。
就地初始化
就地初始化指的是:在定义时直接给出初始值
public String name;
public double score;
public int age;
public static String classes = "宝宝班";
静态代码块初始化
那什么是代码块呢?下一篇继续~
|
以上就是今天要讲的内容了,希望对大家有所帮助,如果有问题欢迎评论指出,会积极改正!!下一篇文章会继续讲述Java的内部类的相关知识,期待大家支持,谢谢~