封装:就是将数据和操作数据的方法进行结合,隐藏对象的属性和方法,仅对外实现一些接口和对象进行交互
其实就是:将类的实现细节(属性和方法)进行隐藏,对外只提供一些交互的接口
在Java中定义了四种权限修饰符,来控制方法或者属性能否直接在类外使用。
访问修饰限定符 =》权限
我们的四种权限修饰符:
private 《》 默认权限 《》protected 《》 public
public是四种权限修饰符里面范围最大的一个,无论是否在同一个包或者是否在同一类中,public修饰的,始终都能被访问。
就好比人的外貌,任何一个人都能看见
class student{
public String name;
public int age;
public student(String name, int age) {
this.name = name;
this.age = age;
}
public void show()
{
System.out.println("name:"+name+" "+"age:"+age);
}
}
public class Test5 {
public static void main(String[] args) {
student student=new student("zhangsan",20);
student.name="lisi";
student.age=21;
}
}
我们可以在主类中,随意的修改student类中的,属性
private权限只能在本类中使用,在其他类和包中不能够使用。
当我们使用private修饰name变量的时候,我们在主类中就不能修改变量了。
相要修改的话,就需要在类中构建getname和setname来获取和修改。
class student{
private String name;
public int age;
public student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show()
{
System.out.println("name:"+name+" "+"age:"+age);
}
}
public class Test5 {
public static void main(String[] args) {
student student=new student("zhangsan",20);
student.setName("lisi");
student.getName();
student.age=21;
}
}
默认权限就是我们在定义变量的时候,前面什么也不写,没有任何的修饰符。
在同一个包的不同类,或者同一个包的同一个类 中都可以,
String name;
class Student1{
String name;
public int age;
public Student1(String name, int age) {
this.name = name;
this.age = age;
}
public void show()
{
System.out.println("name:"+name+" "+"age:"+age);
}
}
public class Test5 {
public static void main(String[] args) {
Student1 student1=new Student1("lisi",20);
student1.show();
}
}
包的概念:为了更好地管理类,把多个类放在一起成为一组,称为软件包。
在Java中也引入了包,包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
Java中提供了很多现成的类,比如Scanner Data可以使用Java.util.Data
因此我们就会自动导入这些包,比如
可以使用 import语句导入包
此外我们还会简单的写成,以下格式
import java.util.*;
import java.sql.*
但是这个样子就会有问题,如果一个类中有两个包,那么这么写的话我们不知道该用的是哪一个。
所以我们更推荐第一种写发
另外可以使用import static导入包中静态的方法和字段。
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 30;
double y = 40;
// 静态导入的方式写起来更方便一些.
// double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
double result = sqrt(pow(x, 2) + pow(y, 2));
System.out.println(result);
}
}
常见的包
- java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
- java.lang.reflect:java 反射编程包;
- java.net:进行网络编程开发包。
- java.sql:进行数据库开发的支持包。
- java.util:是java提供的工具程序包。(集合类等) 非常重要
- java.io:I/O编程开发包。
成员变量分为:
1.静态成员变量/类变量/类成员
2.非静态成员变量/普通成员变量
静态的不依赖对象,不属于对象,所以不需要通过对象的引用就可以来直接访问。
我们定义了一个,静态的变量day,在主函数中我们没有实例化对象,直接通过类名来访问。
import javax.xml.crypto.Data;
import java.util.Arrays;
import java.util.Scanner;
class Classmate
{
public String name;
public int age;
public static int day=10;
public Classmate(String name, int age ,int day) {
this.name = name;
this.age = age;
}
public void show()
{
System.out.println("name:"+name+"age:"+age);
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Classmate.day);
}
}
成员方法:
1.静态成员方法/类方法
2.非静态成员方法
这里有三点是需要大家务必记住的。
1.在静态方法内部,不能直接调用非静态成员方法
如果调用的话会直接报错的。
2.在静态方法内部,不能直接调用非静态的数据成员,要想调用的话需要通过对象的引用来调用。
3.静态方法内部不能使用this关键字
对于这种获取静态成员变量或者设置静态成员变量,此时的方法最好是静态的,如果不是静态的你就还要实例化对象,没有意义。
1.直接赋值,在定义的时候就是直接给变量赋值
public static int day=10;
2.默认初始化
当我们在定义的时候,不给赋值,那么就会自动进行默认赋值。
public static int day;
3.通过get和set方法进行初始化
public static int getDay() {
return day;
}
public static void setDay(int day) {
Classmate.day = day;
}
4.在构造对象的时候,在构造方法中进行赋值
但是这个一般不常用(甚至就不用),所以这里就不讲解了。
5.通过代码块进行赋值
1.普通代码块
2.构造代码块/非静态代码块/实例代码块
3.静态块
4.同步代码块
普通代码块:就是在方法的内部,使用的比较少
public void show()
{
System.out.println("name:"+name+" "+"age:"+age);
{
System.out.println("普通代码块");
}
{
int x=10;
System.out.println(x);
}
}
构造代码块/非静态代码块/实例代码块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量。
class Student1{
String name;
public int age;
public Student1() {
System.out.println("构造方法");
}
{
this.name="lisi";
this.age=10;
System.out.println("构造代码块");
}
public void show()
{
System.out.println("name:"+name+" "+"age:"+age);
{
System.out.println("普通代码块");
}
}
}
public class Test5 {
public static void main(String[] args) {
Student1 student1=new Student1();
student1.show();
}
}
这里大家需要注意:代码是先执行构造代码块的,然后执行构造方法,最后执行普通代码块。
静态代码块:使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
class Student1{
String name;
public int age;
public static int high;
public Student1() {
System.out.println("构造方法");
}
{
this.name="lisi";
this.age=10;
System.out.println("构造代码块");
}
static {
high=100;
System.out.println("静态代码块");
}
public void show()
{
System.out.println("name:"+name+" "+"age:"+age+"high:"+high);
{
System.out.println("普通代码块");
}
}
}
public class Test5 {
public static void main(String[] args) {
Student1 student1=new Student1();
student1.show();
System.out.println("=======");
Student1 student2=new Student1();
student2.show();
}
}
这就可以看出来:代码是先执行静态代码,然后是执行构造代码块的,然后执行构造方法,最后执行普通代码块
如果我们定义了两个对象,那么第二次就不会再执行静态代码块了,这是因为,静态代码块就执行一次在整个代码中
注意事项
静态代码块不管生成多少个对象,其只会执行一次
静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
实例代码块只有在创建对象时才会执行
如果一个来类中定义了两个变量,那我们是否可以直接打印这个类名,去获取变量呢?
class Classmate
{
public String name;
public int age;
public Classmate(String name, int age ) {
this.name = name;
this.age = age;
}
public void show()
{
System.out.println("name:"+name+"age:"+age);
}
}
public class Main {
public static void main(String[] args) {
Classmate classmate=new Classmate("lisi",20);
System.out.println(classmate);
}
}
其实这个结果是我们Java自带的toString返回的结果,如果我们想返回我们想要的结果,那么我们就要重写toString就可以了。
当我们重写toString的时候,再次运行程序,我们就会得到我们想要的结果