目录
我们用一个例子来演示,首先定义一个狗(Dog)类
在狗这个类中有狗的属性:名字,颜色。
狗的行为(用方法实现):旺旺叫,摇尾巴
- class Dog {
- public String name;
- public String color;
-
- public void barks() {
- System.out.println(name + "旺旺叫");
- }
-
- public void wag() {
- System.out.println(name + "摇尾巴");
- }
- }
下面在main方法中去实例化这个类
- public class Test {
- public static void main(String[] args) {
- //引用类型
- Dog dog = new Dog();
- }
- }
创建对象和创建数组相似,需要new一个出来,同一个类可以创建多个实例
下面我们对类中的属性进行初始化
第一种方法是直接在类中初始化,这里就不做演示了
第二种方法是用 对象名. (调用普通方法也是如此)
效果如下:
- public class Test {
- public static void main(String[] args) {
- //引用类型
- Dog dog = new Dog();
- dog.name = "来福";
- dog.color = "黑色";
- dog.barks();
- dog.wag();
- }
- }
上面的操作是:new了一个Dog类的对象 dog
然后将dog对象的属性name初始化为:来福。color初始化为:黑色。
然后调用了它的barks方法和wag方法
最后的输出则是:
来福旺旺叫
来福摇尾巴
这里要注意两点:1. 被public修饰的类,类名必须与文件名相同。
2.类的实例相当于是一个引用,new操作之后会在堆区开辟一块空间存放你的类对象,而对象名是在栈区开辟的,里面存放的时候对象的地址。
构造方法是一个特殊的成员方法,会在创建对象的时候编译器会自动调用。
下面是构造方法的创建:
1.构造方法的名字必须与类名相同
2.他没有返回值类型
3.构造方法可以重载
4.如果没有创建构造方法编译器会默认生产一个没有参数的构造方法,但是如果有了构造方法那么编译器将不会创建
5.构造方法的作用就是为对象成员初始化
我们仍然用上面的Dog类举例
- class Dog {
- public String name;
- public String color;
-
- public void barks() {
- System.out.println(name + "旺旺叫");
- }
- public Dog(String a,String b) {
- name = a;
- color = b;
- }
-
- public void wag() {
- System.out.println(name + "摇尾巴");
- }
- }
-
- public class Test {
- public static void main(String[] args) {
- Dog dog = new Dog("来福","黑色");
- dog.barks();
- dog.wag();
- }
- }
输出结果仍然是:
来福旺旺叫
来福摇尾巴
但是要注意一点,这个时候是没有无参构造方法的,如果你创建了一个没有给参数的对象,这是编译器会报错。
this的作用是调用当前类的成员,并且只能在成员方法中使用
比如在调用构造方法时,形参的名字和成员名相同,这时不用this引用就会出现成员没有被初始化的现象。
- class Dog {
- public String name;
- public String color;
-
- public Dog(String name,String color) {
- name = name;
- color = color;
- }
- }
-
- public class Test {
- public static void main(String[] args) {
- Dog dog = new Dog("来福","黑色");
- }
- }
这是因为 Java中就近原则 会将重名的元素默认调用最近的,而这里最近的就是形参变量,所以相当于形参吧自己赋值给了自己,成员根本没有被赋值。
这是this的作用就体现出来了
我们只需要在变量前面加上一个 this. 就可以解决这个问题
- class Dog {
- public String name;
- public String color;
-
- public Dog(String name,String color) {
- this.name = name;
- this.color = color;
- }
- }
-
- public class Test {
- public static void main(String[] args) {
- Dog dog = new Dog("来福","黑色");
- }
- }
这时dog的成员就被成功赋值了
this后面也可以跟方法
- class Dog {
- public String name;
- public String color;
-
- public void barks() {
- System.out.println(name + "旺旺叫");
- }
- public Dog(String a,String b) {
- name = a;
- color = b;
- this.barks();
- }
- }
-
- public class Test {
- public static void main(String[] args) {
- Dog dog = new Dog("来福","黑色");
- }
- }
this还可以调用构造方法
用this() 括号里面根据要调用的构造方法的参数来给实参。
不过要注意:this()必须在构造函数的第一条语句,并且要注意不要形成调用环,会报错
- class Dog {
- public String name;
- public String color;
- public Dog() {
- this("来福","黑色");
- }
- public Dog(String a,String b) {
- name = a;
- color = b;
- }
- }
-
- public class Test {
- public static void main(String[] args) {
- Dog dog = new Dog();
- }
- }
所谓封装就是对成员变量进行访问限制,然后对外面放出一些公开的“接口” 让外界可以通过这些接口来给成员赋值和取值。
这里先简单说明一些访问权限修饰符的范围
private:同包同类
default(什么都不加):同包同类、不同类
protected:同包同类、不同类,不同包子类
public:同包同类、不同类,不同包子类、非子类
总的来说public哪都能用,private除了在类中哪都不能用,下面也只用这两种。
我们对name这个成员进行封装,向外界提供了setName方法来对name赋值和getName方法让外界可以获取到name这个成员里面的数据。
- class Dog {
- private String name;
- public void setName(String name) {
- this.name = name;
- }
- public String getName() {
- return this.name;
- }
- public String color;
- }
-
- public class Test {
- public static void main(String[] args) {
- Dog dog = new Dog();
- dog.setName("来福");
- String m = dog.getName();
- }
- }
static修饰成员变量
static修饰的成员变量不属于某一个对象,是所有对象共享的
static修饰成员方法
也是共享的,static方法中只能使用静态成员变量
他们的使用方法相同
成员变量:类名/对象 . 变量名
成员方法:类名/对象 . 方法名(...)
- class Dog {
- private String name;
- public static String color = "黑色";
- public static void func() {
- System.out.println(color + "*****");
- }
- }
-
- public class Test {
- public static void main(String[] args) {
- Dog.func();
- String m = Dog.color;
- }
- }
static成员变量的初始化除了在定义是赋值还可以在静态代码块中赋值。
如下
这里讲述普通代码块,实例代码块(也叫构造代码块),静态代码块
普通代码块
定义在方法中的代码块
- public static void main(String[] args) {
- int a = 10;
- {
- a = 20;
- }
- a = 30;
- }
实例代码块
定义在类中的代码块,没有修饰符修饰,一般用于初始化实例成员变量
- class Dog {
- private String name;
- {
- this.name = "来福";
- }
- }
只有创建对象时才会执行
静态代码块
被static修饰的代码块,一般用于初始化静态成员变量
- class Dog {
- public static String color;
- static{
- color = "黑色";
- }
- }
静态代码块不管生成多少个对象 都只执行一次
如果有多个静态代码块,按照定义的先后顺序执行