面向对象三大特性之封装
对象创建的过程
对象创建的过程:
1.为对象分配空间并赋默认值(属性)
2.初始化对象的属性为属性赋初始值
3.调用构造方法创建对象 如果是有参构造 有参构造为属性赋值
引用之间的传递
引用:
Student s1 = new Student();
s1叫做这个学生对象的引用
注意:
1.基本数据类型之间传递是值
2.引用数据类型之间传递的是地址引用
案例:
public class Demo{
public static void main(String[] args) {
int a = 3;
int b = a;
b++;
System.out.println(a);
Student s1 = new Student();
s1.age = 20;
Student s2 = s1;
s2.age++;
System.out.println(s1.age);
}
}
class Student{
String name;
int age;
}
案例:
public class Demo{
public static void main(String[] args) {
Student s1 = new Student();
s1.age = 20;
m1(s1);
System.out.println(s1.age);
}
public static void m(int a) {
a++;
}
public static void m1(Student s) {
s.age++;
}
}
class Student{
String name;
int age;
}
案例:
public class Demo{
public static void main(String[] args) {
Student s1 = new Student();
s1.age = 20;
m1(s1);
System.out.println(s1.age);
}
public static void m(int a) {
a++;
}
public static void m1(Student s1) {
s1 = new Student();
s1.age++;
}
}
class Student{
String name;
int age;
}
this关键字
this.
this:这个的意思 谁调用我我就代表谁 代表的是当前对象的引用
应用场景
案例:解决成员变量和局部变量重名问题 如果想要访问成员变量那么必须要在属性前加this
public class Demo{
public static void main(String[] args) {
Person p1 = new Person();
p1.speakAge();
}
}
class Person{
String name;
int age = 18;
public Person() {
}
public Person(String n,int a) {
name = n;
age = a;
}
public void speakAge(){
int age = 20;
System.out.println(this.age);
}
}
案例:在有参构造方法中为属性赋值时 形参名(局部变量)和属性名重名 需要用this.解决 否则会出现赋值失败问题
备注:在开发中 有参构造的形参名一般和属性名相同 所以一定会采用this.解决赋值失败问题
public class Demo{
public static void main(String[] args) {
Person p1 = new Person("刘洋",14);
System.out.println(p1.name+"--"+p1.age);
}
}
class Person{
String name;
int age = 18;
public Person() {
}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
}
this()和this(参数)
this(): 用于在构造方法中调用无参的构造方法
public class Demo{
public static void main(String[] args) {
Person p1 = new Person("屎壳郎",16);
}
}
class Person{
String name;
int age = 18;
public Person() {
System.out.println("无参构造被调用");
System.out.println("这是10000行初始化代码");
}
public Person(String name) {
this();
this.name = name;
System.out.println("一个参数的构造方法");
}
public Person(String name,int age) {
this();
this.name = name;
this.age = age;
System.out.println("两个参数的构造方法");
}
}
练习:
将这个案例改成 两个参数调用一个参数构造 一个参数构造 调用无参的构造
案例:构造方法间嵌套调用
public class Demo{
public static void main(String[] args) {
Person p1 = new Person("屎壳郎",16);
}
}
class Person{
String name;
int age = 18;
public Person() {
System.out.println("无参构造被调用");
System.out.println("这是10000行初始化代码");
}
public Person(String name) {
this();
this.name = name;
System.out.println("一个参数的构造方法");
}
public Person(String name,int age) {
this(name);
this.age = age;
System.out.println("两个参数的构造方法");
}
}
案例:构造器之间不能递归调用
public class Demo{
public static void main(String[] args) {
Person p1 = new Person("屎壳郎",16);
}
}
class Person{
String name;
int age = 18;
public Person() {
this("屎上飞",77);
System.out.println("无参构造被调用");
System.out.println("这是10000行初始化代码");
}
public Person(String name) {
this();
this.name = name;
System.out.println("一个参数的构造方法");
}
public Person(String name,int age) {
this(name);
this.age = age;
System.out.println("两个参数的构造方法");
}
}
案例:构造器不能自己调用自己
public Person() {
this();
System.out.println("无参构造被调用");
System.out.println("这是10000行初始化代码");
}
案例:this()和this(参数) 必须放在构造方法的第一条语句
public Person(String name,int age) {
this.age = age;
System.out.println("两个参数的构造方法");
this(name);
}
案例:一个构造方法中只能有一个 this() 或者 this(参数)
public Person(String name,int age) {
this();
this(name);
this.age = age;
System.out.println("两个参数的构造方法");
}
案例:this() 和 this(参数) 只能使用在构造方法中
class Person{
String name;
int age = 18;
public Person() {
System.out.println("无参构造被调用");
System.out.println("这是10000行初始化代码");
}
public Person(String name) {
this();
this.name = name;
System.out.println("一个参数的构造方法");
}
public Person(String name,int age) {
this(name);
this.age = age;
System.out.println("两个参数的构造方法");
}
public void m1(String name,int age) {
this(name,age);
}
}
封装
私有:
public 公开的
private 私有的
private 修饰的属性只能在本类中访问
封装思想:
1.私有化类中所有的属性
2.对外提供公开的 get(获取属性值的方法) set(设置属性值的方法) 方法
案例:
public class Demo{
public static void main(String[] args) {
Person p1 = new Person("赵四",250);
p1.printSx();
}
}
class Person{
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
案例:标准的封装
public class Demo{
public static void main(String[] args) {
Person p1 = new Person();
p1.setName("刘洋");
p1.setAge(360);
System.out.println(p1.getName());
System.out.println(p1.getAge());
}
}
class Person{
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
注意:
在开发中定义get/set方法的语法一般采用 set属性名首字母大写形式
eg: 属性 int age;
set/get方法的形式
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
如果不采用 小心挨骂
一个人 当他的年龄超过了18岁 向外人展示的年龄是 永远是18 反之 正常的展示自己的年龄
案例:
public class Demo{
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(23);
p1.setName("哈士奇");
System.out.println(p1.getName());
System.out.println(p1.getAge());
}
}
class Person{
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
if (age<=18) {
return this.age;
} else{
return 18;
}
}
public void setAge(int age) {
if (age>=0&&age<=150) {
this.age = age;
} else {
System.out.println("非法数据 请重新赋值");
this.age = -1;
}
}
}
总结:
1.封装一个类型步骤
1)为类中每个属性进行私有化 用 private 修饰
2)对外提供公开的get/set方法
2.封装的好处
可以在创建对象的时候,对属性的赋值进行安全过滤 ,实现数据的合法性
18.
public class Demo{
public static void main(String[] args) {
Book b1 = new Book("java编程思想",4000);
b1.setTitle("java就该这样学");
b1.setPageNum(150);
System.out.println(b1.getTitle());
System.out.println(b1.getPageNum());
}
}