从零开始的Java开发1-3-2 Java封装包packagestatic关键字代码块
Posted karshey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开始的Java开发1-3-2 Java封装包packagestatic关键字代码块相关的知识,希望对你有一定的参考价值。
文章目录
封装
- 将类的某些信息隐藏在类内部,不允许外部程序直接访问
- 通过该类提供的方法来实现对隐藏信息的操作和访问
- 隐藏对象的信息,也留出访问的接口
三个步骤
实现步骤:
- 修改属性的可见性:设为private
- 创建getter/setter方法:设为public用于属性的读写
- 在getter/setter方法中加入属性控制语句:对属性值的合法性进行判断
举个例子:
类Cat中的name属性设为private:
private String name;
则测试类中会报错:属性不可被访问。
创建get/set方法
//get方法
public String getName()
return this.name;
//set方法
public void setName(String name)
在get/set方法中添加对属性的限制
(其实就是在对应方法里写方法体)
//get方法
public String getName()
return this.name;
//set方法
public void setName(String name)
this.name=name;
测试类:
one.setName("A");
System.out.println("我叫"+one.getName());
输出:
我叫A
关于在get/set方法中添加对属性的限制
如:
public void setAge(int age)
if (age < 0)
System.out.println("年龄不能为负数");
else this.age = age;
在测试类中运行:
one.setAge(-3);
System.out.println("年龄是" + one.getAge());
输出:
年龄不能为负数
年龄是0
则-3没有被输入进年龄——被限制了。
补充:与构造函数联动。
若类的内容如下:
public class Cat
int age;
public int getAge()
return age;
public void setAge(int age)
if (age < 0)
System.out.println("年龄不能为负数");
else
this.age = age;
public Cat(int age)
this.age = age;
测试类:
public static void main(String[] args)
Cat one = new Cat(-3);
System.out.println("年龄是" + one.getAge());
输出:
年龄是-3
这里构造函数直接赋值,没有使用set函数——没有限制。
但如果:
构造函数如下:
public Cat(int age)
setAge(age);
输出:
年龄不能为负数
年龄是0
这里set有限制,所以-3没有被输入进age属性。
eclipse自动生成get和set方法
右键-Sourse-Generate Getters and Setters
然后就可以选要自动生成的方法:
Select All后:
public int getAge()
return age;
public void setAge(int age)
this.age = age;
public double getWeight()
return weight;
public void setWeight(double weight)
this.weight = weight;
public String getSpecies()
return species;
public void setSpecies(String species)
this.species = species;
使用包进行类管理
在Java中,我们通过包来管理Java文件,解决同名文件冲突问题。
假设我们现在要创建一个新的类,也叫Cat,用来描述机器猫。
创建包
在同一个包中不能有同名的类:
所以我们这里要创建一个新的包:
命名(习惯)方式:域名倒序+模块+功能。(——全小写)
包名:com.machine
在包里创建一个Cat类:
package com.machine;//表示这个类是封装在这个包里的——一定要放在第一行
public class Cat
导入包
定义包:package com.test
表示当前类封装在这个包里的。
导入包(三种方法):
加载包中所有
的类:.*
:import com.pet.*;
加载包中特定
的类:import com.pet.Cat
只加载了Cat类
如:导入了所有类,则两个类都可以调用。
如:只导入了一个类,则另一个类不能调用:
一般来说:导入包中的某个类效率更高。
在程序中可以直接加载某个类:
//直接加载com.pet.CatTest
com.pet.CatTest t=new com.pet.CatTest();
这样就不会报错了:
如果想同时导入pet里的Cat和machine里的Cat怎么办?
不能两个都是Cat:
解决方法1:把一个变成导入包中所有的类。
那么问题来了:如果我们这里要实例化一个Cat类,我们实例化的是pet的Cat还是machine的Cat?
我们令两个Cat类的构造函数分别为:
package com.pet;
public class Cat
public Cat()
System.out.println("我是pet.Cat");
package com.machine;
public class Cat
public Cat()
System.out.println("我是machine.Cat");
测试类如下:
package com.test;
import com.pet.Cat;
import com.machine.*;
public class Test
public static void main(String[] args)
Cat cat1=new Cat();
输出:
我是pet.Cat
若先导入import com.machine.*;
,输出也是我是pet.Cat
。
则:加载类的顺序跟import语句的位置无关,会先去找能够直接解析到的类。
这里可以直接解析到pet.Cat的Cat,所以先找到的是pet的Cat。
如果我们想访问machine的Cat,我们就要在程序中直接写出machine.Cat:
com.machine.Cat cat1=new com.machine.Cat();
输出:
我是machine.Cat
那么问题来了,我们可以通过com.machine.*
找到这个包下所有的类,那我们可以通过com.*
找到com包下所有的类吗?——不可以。
会报错:无法解析到CatTest类。
原因是:import 包名.*; 只能访问指定包名下的类,无法访问其子包下的类。
在这里,com下面只有machine,pet,test三个包,没有类,所以没有类可以访问。
包的总结
作用:
- 管理Java文件
- 解决同名文件冲突
定义包
语法:package 包名;
- 必须放在Java源文件中的第一行
- 一个Java源文件中只能有一个package语句
- 包名全部英文小写
- 命名方式:域名倒序+模块+功能
导入包
语法:import 包名.类名;
加载包中所有
的类:.*
:import 包名.*;
加载包中特定
的类:import 包名.类名;
系统常用包
关于调试
static关键字
static表示静态信息。
一些代码:
Cat类:
package com.pet;
public class Cat
// 属性:昵称、年龄、体重、种类、售价
private String name;
private int age;
private double weight;
private String species;
private int price;
//封装:get方法和set方法
public String getName()
return name;
public void setName(String name)
this.name = name;
public int getAge()
return age;
public void setAge(int age)
this.age = age;
public double getWeight()
return weight;
public void setWeight(double weight)
this.weight = weight;
public String getSpecies()
return species;
public void setSpecies(String species)
this.species = species;
public int getPrice()
return price;
public void setPrice(int price)
this.price = price;
测试类:
package com.test;
import com.pet.Cat;
public class Test
public static void main(String[] args)
Cat one = new Cat();
// 用set类赋值
one.setName("A");
one.setAge(2);
one.setPrice(2000);
one.setSpecies("英短");
Cat two = new Cat();
two.setName("B");
two.setAge(1);
two.setPrice(100);
two.setSpecies("中华田园");
System.out.println(one.getName()+"的价格为:"+one.getPrice());
System.out.println(two.getName()+"的价格为:"+two.getPrice());
输出如下:
A的价格为:2000
B的价格为:100
接下来进行一些修改:
public static int price;
price变成了斜体
且测试类中直接对price属性进行访问:会得到提示——要对它进行静态的访问。
添加了static
后再次运行测试类,输出得到:
A的价格为:100
B的价格为:100
——原因是:
static表示静态。
被静态关键字修饰的成员为静态成员,也称为类成员。
无论类实例化多少对象,这个成员都会用同一份内存空间。
静态成员特征:
- 类对象共享
- 类加载时产生,销毁时释放,生命周期长
静态成员的访问方法:
类名.静态成员
——无警告对象名.静态成员
——有警告
在上面的代码里,price是Cat类的静态成员,所以这样访问:int a=Cat.price;
这样就没有警告信息了。
代码:
package com.test;
import com.pet.Cat;
public class Test
public static void main(String[] args)
Cat one = new Cat();
// 用set类赋值
one.setName("A");
//两种访问方法
one.setPrice(2000);
Cat.price=100;
System.out.println(one.getName()+"的价格为:"+one.getPrice());
结果如下:
A的价格为:100
静态方法
把static
放到方法前,也成为类方法。
调用方法:
- 通过对象名调用
- 通过类调用(推荐)
静态方法不能访问非静态方法
这里eat如果想访问run,则可以把run改成静态方法:
这样就不报错了。
——静态方法不能直接访问同一个类的非静态成员,只能直接调用同一个类的静态成员
一个静态方法不能访问非静态属性的例子:
一个静态方法中间接访问非静态成员的例子:通过对象实例化后,对象.方法的方式访问
public static void run()
Cat temp = new Cat();
temp.eat();
System.out.println("run!");
public void eat()
System.out.println("eat!");
这样不会报错。
类前面不能加static
只能加:public
,abstract
,final
局部变量前不能加static
只能加final
;
代码块
普通代码块
在普通方法中。
顺序执行,先出现,先执行。
如类Cat中有方法如下:
public void run()
System.out.println("普通代码块1");
System.out.println("run!");
System.out.println("普通代码块2");
调用one.run();
,输出:
普通代码块1
run!
普通代码块2
构造代码块
在类中定义。
创建对象时调用,优先于构造方法执行
可以有多个。
如:
public class Cat
public void run()
System.out.println("普通代码块1");
System.out.println("run!");
System.out.println("普通代码块2");
System.out.println("构造代码块1");
调用one.run();
,输出:
构造代码块1
普通代码块1
run!
普通代码块2
静态代码块
在代码块前加关键字static
类加载时调用,优先于构造代码块执行。
可以有多个。
public class Cat
public void run()
System.out.println("普通代码块1");
System.out.println("run!");
System.out.println("普通代码块2");
System.out.println("构造代码块1");
static
System.out.println("静态代码块1");
调用one.run();
输出:
静态代码块1
构造代码块1
普通代码块1
run!
普通代码块2
静态代码块,无论实例化多少次对象,都只会执行一次。
构造代码块,每实例化一次对象都会执行一次。
——仅希望执行一次的代码可以放在静态代码块中。
类如下:
public class Cat
System.out.println("构造代码块1");
static
System.out.println("静态代码块1");
测试类如下:
Cat one = new Cat();
Cat two = new Cat();
输出:
静态代码块1
构造代码块1
构造代码块1
普通代码块、构造代码块中可以给属性赋值(静态或非静态)。
静态代码块中只能给静态属性赋值。
与静态方法中的成员调用相似。
总结
面向对象编程的三大特征
- 封装
- 继承
- 多态
封装
- 通过该类提供的方法来实现对隐藏信息的操作和访问
- 隐藏对象的信息,留出访问的接口
特点
- 只能通过规定的方法访问数据
- 隐藏类的实例细节,方便修改和实现
步骤
- 修改属性的可见性:设为private
- 创建getter/setter方法:设为public用于属性的读写
- 在getter/setter方法中加入属性控制语句:对属性值的合法性进行判断
1:隐藏对象
2、3:留出接口
包:
——作用
- 管理Java文件
- 解决同名文件冲突
定义包
语法:package 包名;
- 必须放在Java源文件中的第一行
- 一个Java源文件中只能有一个package语句
- 包名全部英文小写
- 命名方式:域名倒序+模块+功能
导入包
语法:import 包名.类名;
加载包中所有
的类:.*
:import 包名.*;
加载包中特定
的类:import 包名.类名;
static
- static+属性——静态属性、类属性
- static+方法——静态方法、类方法
- static+类——不存在
- static+方法内局部变量——不存在
- static+(构造)代码块——静态代码块
代码块
在普通方法中:普通代码块
在类中:构造代码块
static+构造代码块:静态代码块
注意
- 静态成员的生命周期:类加载时产生,销毁时释放,生命周期长
- 静态方法中的成员调用:只能直接访问类内的静态成员,如果实在要访问非静态成员,就对象实例化,通过对象的方式来访问
- 各种代码块的执行顺序:静态代码块只执行一次,构造代码块在每次对象构造的时候调用
以上是关于从零开始的Java开发1-3-2 Java封装包packagestatic关键字代码块的主要内容,如果未能解决你的问题,请参考以下文章
从零开始搭建Java开发环境第二篇:如何在windows10里安装MySQL