从零开始的Java开发1-3-1 Java面向对象:创建类实例化对象单一职责原则newthis构造方法
Posted karshey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开始的Java开发1-3-1 Java面向对象:创建类实例化对象单一职责原则newthis构造方法相关的知识,希望对你有一定的参考价值。
文章目录
面向对象
类和对象
类是模型,确定对象将会拥有的特征(属性)和行为(方法)
对象是类的实例化表现
类是对象的类型
对象是特定类型的数据
属性和方法
属性:对象所具有各种静态特征——对象有什么
方法:对象具有的各种动态行为——对象能做什么
类和对象的关系
类
- 抽象的概念
- 模板
对象
- 一个看得到、摸得着的具体实体
流程:创建类——实例化对象——完成具体的程序
创建类
在Java中,可以通过包(package)对类(class)进行管理。
包名:
- 英文小写
- 域名倒序
一个宠物猫类:
package com.pet;
public class Cat
// 属性:昵称、年龄、体重、品质
String name;
int age;
double weight;
String species;
// 方法:跑、吃
// 跑
public void run()
System.out.println("run!");
// 吃
public void eat()
System.out.println("eat!");
实例化对象
package com.pet;
public class CatTest
public static void main(String[] args)
//对象实例化
Cat one=new Cat();
//测试
one.eat();
one.run();
输出:
eat!
run!
注意,如果一个变量没有赋值,则它不能被打印输出。
但如果一个对象的属性没有被赋值,可以输出。
public class CatTest
public static void main(String[] args)
//对象实例化
Cat one=new Cat();
System.out.println(one.age);
System.out.println(one.name);
输出:
0
null
也就是说,对象的属性没有被初始化,但它会有默认值。
我们可以通过=给对象的属性赋值:
public class CatTest
public static void main(String[] args)
//对象实例化
Cat one=new Cat();
System.out.println(one.name);
one.name="A";
System.out.println(one.name);
输出:
null
A
单一职责原则/单一功能原则
不要存在多于一个导致类变更的原因
一个类中承担的功能越多,它的交融、耦合性就越高,则它被服用的可能性就降低了。而且,若一个类的耦合性高,且类中的某个职责改变了,则同类的其他职责都要改变。
在程序设计中,我们尽量把不同的能引发变化的原因放进不同的类中,这样一来,当某一方发生变化时,对另一方的影响会小很多。
类间如何识别:
先找同一个类,再找同一个包…这样向上找。
new关键字
对象实例化操作:对象创建。
实例化对象的过程:
- 声明对象:Cat one
- 实例化对象:new Cat();
流程:
- 在栈中声明一个对象。
- 在堆中开辟一块空间(new)。
- 通过赋值符号,将堆中开辟的空间地址存放到栈的对象中。
声明对象
在内存的栈区域开辟了一个空间,取名为one:此时one还不是一个有效的对象,因为它是空的。
如:
错误提示:当前对象没有初始化。
实例化对象
在内存的堆中开辟了一块空间,完成了这个对象相关信息的鹅初始化操作。
栈 VS 堆
栈:存放局部变量。
堆:存放动态数据。
基本数据类型(栈)和引用数据类型(栈、堆):
基本数据类型:栈中保存的是值,如:int a=10
会在栈中开辟一个空间,名为a,存的是10;
引用数据类型:栈中保存的是指向堆中具体空间的地址——可以根据它找到在堆中的实例。
用赋值=符号把声明和实例化关联
把堆空间里新开辟的地址存放到了one当中。相当于把一个新房子的钥匙交到了one的手里,one有了钥匙,就可以去房子里了。
Cat one=new Cat();
不同的对象会开辟不同的空间,尽管它们的属性值一样,它们也是不同的对象。
其他实例化方式
Cat two=one;
one里存的是堆中开辟的地址,赋值后,one和two指向同一块内存。
如:
public class CatTest
public static void main(String[] args)
//对象实例化
Cat one=new Cat();
one.age=1;
Cat two=one;
System.out.println("one.age:"+one.age);
System.out.println("two.age:"+two.age);
two.age=2;
System.out.println("one.age:"+one.age);
System.out.println("two.age:"+two.age);
输出:
one.age:1
two.age:1
one.age:2
two.age:2
几点注意事项
需要多此访问同一对象时,必须进行声明
多次访问进行声明:
one.age=1;
one.name="A";
单次访问:匿名对象进行方法调用
new Cat().run();
同一作用范围内,不能定义同名对象
可以同时声明多个引用,用逗号分隔
Cat one,two;
Cat three=new Cat(),four=new Cat();
未使用对象会报错
构造方法
无参构造方法
也成为构造函数、构造器。
- 构造方法与类名相同且没有返回值
- 构造方法的语句格式
- 只能在对象实例化的时候调用
- 当没有指定构造方法时,系统会自动添加无参的构造方法
- 当有指定构造方法,无论是有参、无参的构造方法,都不会自动添加无参的构造方法
- 一个类中可以有多个构造方法
构造方法的语句格式格式:
访问修饰符 构造方法名(可以加参数)
//初始化代码
一个无参的构造方法:
public class Cat
// 属性:昵称、年龄、体重、品质
String name;
int age;
double weight;
String species;
// 一个无参的构造方法
public Cat()
System.out.println("我是无参构造方法");
// 方法:跑、吃
// 跑
public void run()
System.out.println("run!");
// 吃
public void eat()
System.out.println("eat!");
调用one.run();
,输出:
我是无参构造方法
run!
说明==在对象实例化的时候会自动调用构造方法。 ==
如果写了一个带参的构造方法,再直接实例化:会报错——无参的构造方法没有被定义。
因为:
如果没有定义构造方法,系统会自动定义;
如果定义了构造方法,系统不会自动定义,但系统找不到匹配的构造方法,就会报错。
这里,如果想要实例化,要么带参,要么再写一个无参的构造方法。
public Cat(String name)
System.out.println("我是有参构造方法");
带参实例化:
Cat one=new Cat("A");
带参构造方法
代码:
//一个带参构造方法,依次赋值属性
public Cat(String name,int age,double weight,String species)
name=name;
age=age;
weight=weight;
species=species;
出现警告线:
测试类如下,并运行:
public static void main(String[] args)
//对象实例化
Cat one=new Cat("A",2,100.0,"英短");
System.out.println("昵称:"+one.name);
System.out.println("年龄:"+one.age);
System.out.println("体重:"+one.weight);
System.out.println("品种:"+one.species);
输出:
昵称:null
年龄:0
体重:0.0
品种:null
出错了!错误原因是(如上图警告信息):这几个属性并没有起作用。
当我们把鼠标放到参数的name中时,构造方法内的两个name都会被选中。
当我们选中属性中的name时,构造函数内的name无显示:
也就是说,实际上参数中的name并没有赋值给属性,这就是就近原则。
就近原则:优先使用局部变量。 在构造方法中,我们会先找最近的name进行赋值,只有当构造方法中没有name,才会去外面找name。
解决的方法1:属性和参数不要用一样的变量名。
构造函数代码:
//一个带参构造方法,依次赋值属性
public Cat(String name1,int age1,double weight1,String species1)
name=name1;
age=age1;
weight=weight1;
species=species1;
运行测试类后的输出:
昵称:A
年龄:2
体重:100.0
品种:英短
解决的方法2: this关键字。
this关键字
this是当前对象的默认引用,我们可以朴素地理解为:谁调用了这个构造函数,谁就是当前对象。 如代码:
//一个带参构造方法,依次赋值属性
public Cat(String name,int age,double weight,String species)
this.name=name;
this.age=age;
this.weight=weight;
this.species=species;
我们可以通过this
关键字显式地告诉编译器:传入的参数name要赋值给当前对象的name属性。
运行一下测试代码,输出:
昵称:A
年龄:2
体重:100.0
品种:英短
this也可以调用方法,如:这里表示调用run方法时还要调用当前类的eat方法。
public void run()
this.eat();//这里不写this也可以
System.out.println("run!");
调用run()
,输出:
eat!
run!
构造方法调用
如果类里有一个和类名相同的普通方法,不会报错(无语法错误),但会有警告——不推荐这样写。
普通方法不能调用构造方法。
构造方法的调用只能通过构造方法之间来完成。
在构造函数中用this();
调用无参构造函数,this()
必须放在第一行:
// 一个无参构造方法
public Cat()
System.out.println("我是无参构造方法");
// 一个带参构造方法,依次赋值属性
public Cat(String name, int age, double weight, String species)
this();// 这样调用
this.name = name;
this.age = age;
this.weight = weight;
this.species = species;
测试语句:
Cat one = new Cat("A", 2, 100.0, "英短");
输出:
我是无参构造方法
用无参的构造方法调用有参的构造方法:
// 一个无参构造方法
public Cat()
//用this来调用构造方法要放在第一行
this("A", 2, 100.0, "英短");
System.out.println("我是无参构造方法,我要调用有参构造方法");
// 一个带参构造方法
public Cat(String name, int age, double weight, String species)
this.name = name;
this.age = age;
this.weight = weight;
this.species = species;
测试类:
public static void main(String[] args)
// 对象实例化
Cat one = new Cat();
System.out.println("昵称:" + one.name);
System.out.println("年龄:" + one.age);
System.out.println("体重:" + one.weight);
System.out.println("品种:" + one.species);
// one.run();
输出:
我是无参构造方法,我要调用有参构造方法
昵称:A
年龄:2
体重:100.0
品种:英短
总结
关于变量和对象属性的初始化:
- 如果一个变量没有赋值,则它不能被打印输出
- 对象的属性没有被初始化时会有默认值
关于声明对象和实例化对象:
- 声明对象:栈
- 实例化对象:堆
- 实例化对象就是把堆空间里新开辟的地址存放到了栈当中
单一职责原则:不要存在多于一个导致类变更的原因。
构造方法:
- 构造方法与类名相同且没有返回值
- 构造方法的语句格式
- 只能在对象实例化的时候调用
- 当没有指定构造方法时,系统会自动添加无参的构造方法
- 当有指定构造方法,无论是有参、无参的构造方法,都不会自动添加无参的构造方法
- 一个类中可以有多个构造方法
如果没有定义构造方法,系统会自动定义;
如果定义了构造方法,系统不会自动定义,但若系统找不到匹配的构造方法,就会报错。
带参构造方法:
两种对属性起作用的语句:
-参数与属性不同名:
name=name1;//属性是name,参数是name1
- this关键字
this.name=name;
//第一个name是对象的属性name,第二个name是参数
以上是关于从零开始的Java开发1-3-1 Java面向对象:创建类实例化对象单一职责原则newthis构造方法的主要内容,如果未能解决你的问题,请参考以下文章