目录
封装
基本概念:
将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
了解访问修饰限定符:(YES代表可以访问)
访问范围 private 默认 protecte public 1 同一包中的同一类 YES YES YES YES 2 同一包中的不同类 YES YES YES 3 不同包中的子类 YES YES 4 不同包中的非子类 YES
举例1:
//创建一个猫的类 class Cat{ public int age; public String name; private void jump(){ //这里的成员方法使用private修饰 System.out.println(name+"被吓的跳起来"); } public void bark(){ //这里的成员方法使用public修饰 System.out.println(name+"在喵喵喵"); } public Cat(int age, String name) {//构造方法 this.age = age; this.name = name; } } public class Test { public static void main(String[] args) { Cat cat=new Cat(3,"小二"); cat.jump();//正是因为jump这个成员方法使用private修饰的从而起到了封装的作用 限制了其使用范围 //从而使得jump()这个方法只能在 Cat这个类里使用,出了这个类便不能被使用了 cat.bark();//而 bark这个成员方法使用的pubilc修饰,从而其使用范围更大,从而可以在main函数中使用 } }
将该串代码复制到编译器当中,我们会发现 cat.jump(); 会发生报错,正是因为我们使用了private 来修饰 jump()这一成员方法,从而对其进行了封装,使其只能在同一个包中的同一个类进行访问。
举例2:
class Cat{ private int age; //这里的成员变量age我们使用private来进行封装,使其不能直接拿到我们的 age public String name; //既然我们在main函数中不能直接拿到我们的 age这一成员变量 我们可以提供两个成员方法解决该问题 public int getAge() { //这是得到 age这一变量的方法 return age; } public void setAge(int age) {//这是给age这一变量赋值的方法 this.age = age; } } public class Test { public static void main(String[] args) { Cat cat=new Cat(); cat.setAge(5);//这里便可以使用我们所创建的成员方法来对被封装 age 变量赋值 System.out.println(cat.getAge()+"岁啦");//这里便可以使用我们所创建的成员方法来输出打印我们的 age变量 } }
我们自己可以创建两个成员方法(所谓的接口)来实现 对所被封装变量 的初始化和获取该变量。
static成员
例1:(静态成员变量)
class Student{ //普通成员变量 public String name;//名字 public double score;//分数 public int age;//年龄 //静态成员变量 且该变量是不属于对象 public static String classes ="2班"; //当我们加上 final 来修饰我们的静态成员变量时 该变量便变为常量 是不可修改的 // public static final String classes ="2班"; } public class Test { public static void main(String[] args) { //普通成员变量的访问 Student student=new Student();// 创建一个类型为Student的对象student System.out.println(student.name);//普通成员变量一般是对象名加上 '.'来访问 //其静态成员变量的引用 一般用其所在类的类名加上 '.'来访问 System.out.println(Student.classes); } }
当我们定义一个学生类时,例如定义一个都是2班学生的类,这个班级中的学生的姓名和分数一般都是不同的,一般使用普通成员变量,但这个2班是这个类中所有对象学生的共同点,那我们便可以使用static来定义静态成员变量classes,其值是固定的2班,且每个对象学生都是2班的。
特点:
a:静态成员变量并不属于任何一个对象,而是所有对象所共同有的。
b:可以通过对象名来访问,但一般使用类名来访问。
c:静态成员变量跟随类的加载而创建,类的卸载而销毁。
例2:(静态成员方法)
//定义一个种类都为哈士奇的狗类 class Dog{ //普通成员变量 public String name;//名字 public int age;//年龄 //静态成员变量 public static String type="哈士奇"; //普通成员方法 public void bark(){ System.out.println(name+"汪汪汪"); fuc();//我们的静态成员方法可以被普通成员方法直接调用 } //静态成员方法 假设每只哈士奇的主人都十分疼爱自己的狗狗 public static void fuc(){ //当我们直接在静态成员方法使用普通静态成员时会发生报错! //因为静态成员变量的创建是不依赖于对象的,但是name这一普通成员变量是依赖于对象的创建的 //从而便不能直接引用我们的普通成员变量 // System.out.println(name+"的主人很疼爱它"); System.out.println("被主人疼爱"); } // 引用方式1:传一个对象的参数 // public static void fuc(Student student) { // System.out.println(student.name+"的主人很疼爱它"); // } //引用方式2:直接new一个对象 // public static void fuc(){ // Student student =new Student(); // System.out.println(student.name+"的主人很疼爱它"); // } } public class Test2 { public static void main(String[] args) { Dog.fuc();//一般直接使用类名来调用静态成员方法 } }
结论:
a:普通成员方法可直接调用静态成员方法。
b:静态成员方法中不能直接调用非静态的成员变量或者方法。
代码块
普通代码块(本地代码块):
普通代码块是以 { } 的形式 定义在方法之中,但其没什么实质上的意义,所以该代码块很少见!
构造块(实例代码块):
实例代码块是以 { } 的形式 定义在方法的外部 类的内部的!其作用一般可以用来初始化实例成员变量!
静态代码块:
静态代码块是以 { } 前加上static修饰的形式来定义在方法的外部 类的内部的! 其作用一般可以用来初始化静态成员!
举例:
//定义一个四大名著书类 class Book{ //普通成员变量 public String name; public int price; public String type; public static String reputation; //构造方法 public Book(String name, int price, String type) { this.name = name; this.price = price; this.type = type; System.out.println("带有三个参数的构造方法执行!"); } //实例代码块 { this.name="三国演义"; //可用来初始化实例成员 System.out.println("这是实例代码块!"); } //静态代码块 static { reputation="四大名著"; System.out.println("这是静态代码块!"); } //普通成员方法 public void func(){ System.out.println("大家都喜欢读"+name); //普通代码块 { System.out.println("这是普通代码块!"); } } } public class Test { public static void main(String[] args) { Book book=new Book("水浒传",38,"小说"); System.out.println("====================================="); Book book1 =new Book("红楼梦",36,"小说"); } }
输出结果为:
我们可以发现,当我们创建一个对象的时候,该对象所对应的类中依次执行了静态代码块,实例代码块,带三个参数的构造方法 。结论:
a:静态的最先被执行(加载了类 便会被执行) 若有多个静态的 ,看定义顺序,依次执行。
b:没有实例化对象时,只会执行静态的 且实例化多个对象时,静态的都只会执行一次!
c:其次执行实例的 若有多个实例的 ,看定义顺序,依次执行。
d:最后执行构造函数。
内部类
定义:将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类,内部类也是封装的一种体现。
实例内部类:
class OuterClass{ //外部类 //普通成员变量 public int data1=1; private int data2=2; //静态成员变量 public static int data3=3; class InnerClass{ //内部类 public int data1=250; private int data4=4; //实例内部类一般不能定义静态的成员变量,如果需要定义静态成员变量,则该变量应该被final所修饰。 public static final int data3 =5; //实例内部类绝对不能定义静态的成员方法! //内部类的构造方法 public InnerClass(){ System.out.println("内部类的构造方法!!!"); } //内部类普通成员方法 public void func(){ System.out.println("实例内部类的普通方法!"); //在内部类中调用与外部类同名的成员变量时,优先访问自己的 System.out.println("内部类的普通成员变量data1:"+data1); //如果需要访问外部类的同名成员变量,格式为 外部类名.this.成员名 System.out.println("外部类的普通成员变量data1:"+OuterClass.this.data1); //内部类可直接访问外部类成员 System.out.println("外部类的普通成员变量data2:"+data2); System.out.println("内部类的静态成员变量data3:"+data3); System.out.println("外部类的静态成员变量data3:"+OuterClass.data3); } // 外部类中访问内部类成员时,得先实例化一个内部类对象! public void func2(){ InnerClass innerClass=new InnerClass(); System.out.println(innerClass.data1); } } } public class Test { public static void main(String[] args) { //当我们要实例化一个内部类对象时,我们必须得先实例化外部类对象 OuterClass outerClass=new OuterClass(); //实例化一个内部类对象的一般格式 //外部类的类名.内部类类名 内部类对象名 = 外部类对象名.new 内部类名(); OuterClass.InnerClass innerClass= outerClass.new InnerClass(); //可以简写为 OuterClass.InnerClass innerClass2= new OuterClass().new InnerClass(); innerClass.func(); } }
输出结果为:
静态内部类:
class OuterClass { public int data1 = 1; private int data2 = 2; public static int data3 = 3; static class InnerClass {//静态内部类 public int data4 = 4; private int data5 = 5; public static int data6 = 6; // 定义一个 类型为 OOuterClass 名为outer的变量; public OuterClass outer; //不带参数的内部类的构造方法 public InnerClass() { System.out.println("不带参数的静态内部类的构造方法!!!"); } //带参数的静态内部类的构造方法 public InnerClass(OuterClass outerClass) {//直接传入一个外部类对象 System.out.println("带参数的静态内部类的构造方法!!!"); this.outer = outerClass; //将传入的外部类对象 赋给内部类中的 outer变量 } public void func() { System.out.println("func方法执行了!"); //静态内部类中能直接访问外部类静态成员变量或方法 System.out.println("外部类静态成员变量data3:"+data3); //System.out.println(data1); 在静态内部类中不能直接访问外部类普通成员变量或方法 //静态的 是不依赖于对象的 有可能在用该方法时 外部类对象都未生产,从而没有 data1 之类的成员变量 //当我们需要访问时可以直接实例化一个外部类对象 从而可用 对象名.data1 的格式来直接访问 OuterClass outerClass =new OuterClass(); System.out.println("外部类普通成员变量data1:"+outerClass.data1); //或者我们在实例化内部类对象时传一个外部类对象 //此时我们可以直接使用 outer.外部类成员变量名 来访问外部类成员变量或方法 System.out.println("外部类普通成员变量data1:"+outer.data1); System.out.println("外部类普通成员变量data2:"+outer.data2); System.out.println("内部类普通成员变量data4:"+data4); System.out.println("内部类普通成员变量data5:"+data5); System.out.println("内部类静态成员变量data6:"+data6); } //内部类的静态成员方法 public static void func2() { System.out.println("内部类的静态成员方法func2"); } } } public class Test { public static void main(String[] args) { //当我们想实例化一个静态内部类对象时,我们知道静态的 是不依赖于对象的 //从而格式为 外部类的类名.内部类类名 内部类对象名 = new 外部类类名.内部类类名(); OuterClass.InnerClass innerClass =new OuterClass.InnerClass(); //直接传入一个外部类对象 OuterClass.InnerClass innerClass2 =new OuterClass.InnerClass(new OuterClass()); innerClass2.func(); } }
输出结果:
局部内部类:
public class Test2 { public static void func(){ //局部内部类只能在该方法体中使用,不能在出该方法体的外部使用,所以我们一般很少用到局部内部类 class A{//定义在方法内部的类为局部内部类 局部内部类不能被 public static 等访问修饰限定符修饰 public void func(){ System.out.println("520"); } } A a = new A(); a.func(); } public static void main(String[] args) { func(); } }
输出结果为:
以上就是类和对象的基础知识(2)的全部内容!!
如有错误或者能改进的地方 请各大佬指出 我会及时改正!!