一、成员变量与局部变量比较
1、定义的位置不同
A.成员变量定义在类中方法外 局部变量定义在方法中
2、生命周期不同
成员变量随着对象的加载而加载 随着对象的消失而消失
局部变量随着方法调用而加载 随着方法的结束而结束
3、存的位置不同
成员变量是存在堆内存中 局部变量是存在栈内存中
4、是否有默认值
局部变量没有默认值 局部变量必须先赋值 才能使用
成员变量是有默认值
整数类型 0 小数类型 0.0 字符类型 '\u0000' 布尔类型 false 引用类型 null
二、封装
1、概念
A.生活中的封装 快递打包
B.隐藏属性内部细节 提供对外访问的方法 例如:锁门==>钥匙
2、原则:
A.隐藏属性内部实现细节(锁门)
B.提供对外访问的方法(钥匙)
3、好处:
A.提高代码的安全性
B.提高代码的可拓展性与可维护性
4、体现:
A.对属性的封装
B.对工具类的封装 加密 解密工具类 时间格式化工具类 字符串工具类 json工具类
5、对属性进行封装 使用关键字 private
A.关键字: private 私有 私人
B.修饰成员 类 方法 变量……
C.使用private进行修饰 只能本类进行访问
6.方案
A.问题:
使用private进行修饰的成员 只能本类进行访问
B.解决:
提供两个对外访问的方法 setxxx() getxxx() ==>xxx 表示的是属性的名词
setxxx() ==>用于来设置值
getxxx() ==>用于来获取值
7、方案
问题:方法的参数名与成员变量的名称相同 导致成员变量赋值失败
原因:
变量的访问时离声明变量最近的地方
局部变量的优先级大于成员变量 ==>等同于优先访问局部变量
解决:
使用关键字 this 表示当前对象的引用==>就是当前对象
this.变量名==>访问的时成员变量
this.方法名==>访问的时成员方法
this()==>访问是构造方法
8、快捷键
alt+insert
代码-01
package com.qf.test01; public class Student { private String name; private int age; public void setName(String n){ name=n; } public String getName(){ return name; } public void setAge(int ag) { age = ag; } public int getAge(){ return age; } }
代码-01
package com.qf.test01; public class Test01 { public static void main(String[] args) { //实例化对象 Student xiaoze=new Student(); //给成员变量赋值 // xiaoze.name="小泽老师"; //调用set方法进行赋值 xiaoze.setName("小泽老师"); //取值 System.out.println(xiaoze.getName()); // // xiaoze.age=18; //调用setf方法进行赋值 xiaoze.setAge(18); //取值 System.out.println(xiaoze.getAge()); } }
代码-02
package com.qf.test01; public class Student { private String name; private int age; public void setName(String name){ this.name=name; } public String getName(){ return name; } public void setAge(int age) { if(age<0||age>130){ this.age=10; }else{ this.age = age; } } public int getAge(){ return age; } }
代码-02
package com.qf.test01; public class Test01 { public static void main(String[] args) { //实例化对象 Student xiaoze=new Student(); //给成员变量赋值 // xiaoze.name="小泽老师"; //调用set方法进行赋值 xiaoze.setName("小泽老师"); //取值 System.out.println(xiaoze.getName()); // // xiaoze.age=18; //调用setf方法进行赋值 xiaoze.setAge(18); //取值 System.out.println(xiaoze.getAge()); } }
快捷键
step01
按alt+insert
step02
step03
三、构造
1、构造方法 构造函数 构造器
2、作用:
A.构造方法用于来实例化对象
B.构造方法用于给成员变量赋值
C.所有实例化对象 都是执行构造方法
3、分类:
A.无参构造
B.有参构造
4、语法:
访问修饰符 类名(参数列表){
//给成员对象赋值
}
5、案例
public Student(){
}
6、说明
A.构造方法的方法名必须是类名
B.构造方法是可以使用return; 用于结束构造方法 但不能具体return返回具体的数据
C.构造方法不能自身进行调用 必须由jvm来进行调用
7、注意点
A.在一个类中 如果不提供任何的构造方法 系统会默认提供一个无参的构造方法
B.在一个类中 如果提供了任何的构造方法 系统不会提供无参构造方法
C.构造方法是可以重载的
D.在实际开发中一般会提供两个构造方法 一个是有参构造 一个是无参构造
8、快捷键
alt+insert
9、set方法与构造方法比较
A.相同点:都可以用于来给成员变量赋值
B.不同点:
a.构造方法只能在创建对象的时候 给成员变量赋值一次
b.set方法可以多次给成员变量赋值
四、案例
step01 需求:定义一个企鹅类 属性:名称 性别 爱心值 健康值 方法:打印对象的属性值
实例化5个企鹅对象 通过键盘录入信息 将企鹅对象保存到数组中 并且打打印企鹅的信息(get方法获取)
通过构造方法给属性赋值
step02分析
A.定义一个企鹅类
B.定义一个数组 数组类型 企鹅类
C.使用键盘录入企鹅对象信息 将企鹅对象保存到数组中
D.使用循环遍历 数组 获取属性值
step03代码-定义企鹅类
package com.qf.test.test02; public class Penguin { //私有化属性 private String name; private String sex; private int love; private int health; //提供两个构造方法 无参 有参 public Penguin(){ } public Penguin(String name,String sex,int love,int health){ this.name=name; this.sex=sex; this.love=love; this.health=health; } //get-set方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getLove() { return love; } public void setLove(int love) { this.love = love; } public int getHealth() { return health; } public void setHealth(int health) { this.health = health; } //定义一个print方法 public void print(){ System.out.println(name+"\t"+sex+"\t"+health+"\t"+love); } }
step04-代码-测试类
package com.qf.test.test02; import java.util.Scanner; public class Test { public static void main(String[] args) { //实例化Scanner Scanner input= new Scanner(System.in); //定义一个数组 Penguin [] penguins=new Penguin[2]; //使用循环录入信息 for(int i=0;i<penguins.length;i++){ System.out.println("请输入企鹅的名称:"); String name=input.next(); System.out.println("请输入企鹅的性别:"); String sex=input.next(); System.out.println("请输入企鹅的健康值:"); int health=input.nextInt(); System.out.println("请输入企鹅的爱心值:"); int love=input.nextInt(); Penguin p = new Penguin(name,sex,health,love); penguins[i]=p; } for(int i=0;i<penguins.length;i++){ Penguin p=penguins[i]; p.print(); } } }
五、静态
5.1概念
1、静态关键字:static
2、修饰的成员
A.类
B.方法
C.变量
3、好处
没有静态之前:
多个对象相同属性的时候 需要开辟多个孔吉纳进行存储 浪费内存空间 内存空间资源浪费 修改数据麻烦
有静态之后:
多个对象相同的属性值 只需要在方法去中静态空间开辟一块空间 实现所有对象共享 节省内存空间 修改数据方便
没有静态之前内存图:
有静态之后内存图:
5.2静态变量
1、语法:static 数据类型 变量名
2、静态变量优先与对象先进行加载
3、静态变量是存在方法区中的静态区间中
4、静态变量的访问方式
A.通过类名来进行访问 语法:类名.静态变量名称 例子:Actor.country(推荐)
B.通过对象名来进行访问 语法:对象名.静态变量名称 例子:a1.country
5、静态变量所属类变量 随着类的加载而加载 静态变量不容易被gc进行回收(最后被回收)
5.3静态方法
1、语法:
访问修饰符 static 返回值类型 方法名称(参数列表){
方法体;
return 返回值;
}
2、例子:
public static void showInfo(){
}
3、注意点
A.静态的方法不能访问非静态变量
原因:静态资源优先与对象存在
B.静态方法不能调用非静态方法
原因:与上同理
C.静态方法不能访问this关键字
原因:与上同理
总结:静态方法不能访问非静态资源
5.4静态变量与成员变量的比较
A.所属不同
静态变量属于类变量 成员变量属于对象变量
B.存储位置不同
静态变量是存在方法去中的静态区间中 成员变量是存在堆内存中
C.生命周期不同
a.静态的变量是随着类的加载而加载 是最后被gc进行回收
b.成员变量是随着对象的加载而加载 随着对象的销毁而销毁
D.访问方式不同
a.静态变量调用方式 1、直接通过类名来进行访问(推荐) 2、通过对象名来进行访问
b.成员变量的调用方式 只能通过对象名来进行访问
六、继承
6.1继承的概念
1、继承中至少有两个类 一个父类 一个子类
2、继承关键字 extends
3、继承:就是共性的抽取
4、满足is a 的关系才能使用继承(我是你爸爸 就可以使用继承)
5、子类可以获取父类的资源 但是父类不能获取子类的资源
step01定义员工类
package com.qf.test.test03; public class Emp { String name; int age; }
step02定义老师类
package com.qf.test.test03; public class Teacher extends Emp{ public void work(){ System.out.println("授课........"); } }
step023定义助教类
package com.qf.test.test03; public class Assistant extends Emp{ public void work(){ System.out.println("辅导.........."); } }
step023定义测试类
package com.qf.test.test03; public class Test { public static void main(String[] args) { //实例化老师对象 Teacher t1=new Teacher(); t1.name="小野老师"; t1.age=18; System.out.println(t1.name+"\t"+t1.age); //实例化助教类对象 Assistant t2=new Assistant(); t2.name="拉稀哥"; t2.age=23; System.out.println(t2.name+"\t"+t2.age); //实例化父对象 Emp e=new Emp(); // e.work 父类不能访问到子类的资源 } }
6.2继承的注意点
1、子类不能继承到父类私有(private)的资源
原因:私有的资源(private)只能本类进行访问
2、子类不能继承父类的构造方法
子类不能继承父类的构造方法 但是可以调用父类的构造方法 通过关键字super
访问父类的无参构造 super()
访问父类的有参构造 super(参数列表)
6.3Java单继承问题
1、在Java中 一个类只能有一个直接父类(亲爸爸) 但是可以有间接的父类(爷爷类)
2、Java只支持单继承(只能由一个亲爸爸) 不支持多继承(没有隔壁老王) 但是支持多层继承(可以有爷爷类,太爷爷类……)
3如果一个类没有继承任何类 那么这个类默认继承object object是所有类的直接爸爸或者是间接爸爸
6.4继承访问成员变量的特点
1、特点:
子类访问成员变量的特点 优先访问子类的成员变量 如果子类都没有 则向上进行查找 一直查找到object类 如果object没有则报错
step01父类
package com.qf.test.test04; public class Fu { String name="阿廖"; int age=18; int num=100; }
step02子类
package com.qf.test.test04; public class Zi extends Fu{ String name="老王"; int age=3; int num=99; }
step03测试类
package com.qf.test.test04; public class Test { public static void main(String[] args) { //实例化子类对象 Zi z=new Zi(); System.out.println(z.name+"\t"+z.age+"\t"+z.num); //一直向上查找 如果查找到Object 没有则报错 // System.out.println(z.kk); } }
6.5this与super
1、this 与super
this ==>表示的是当前对象的引用 super ==>当前对象父类对象的引用
2、访问成员变量
this 既可以获取自身的成员变量 也可以获取父类的成员变量
super 只能获取父类的成员变量
3、访问成员方法
this 既可以获取自身的成员方法 也可以获取父类的成员方法
super 只能获取父类的成员方法
4、访问构造方法
this()==>表示调用自身的无参构造方法 this(参数列表)==>b表示调用自身的有参构造方法
super()==>表示调用父类的无参构造方法 super(参数列表)==>表示调用父类的有参构造方法
step01父类
package com.qf.test.test09; public class Fu { int num=10; public void show(){ System.out.println("我是父类方法"); } }
step02子类
package com.qf.test.test09; public class Zi extends Fu{ int num=20; public void show(){ super.show(); System.out.println("我是子类方法"); } public void showInfo(int num){ System.out.println(num); System.out.println(this.num); System.out.println(super.num); } }
step03测试类
package com.qf.test.test09; public class Test { public static void main(String[] args) { //实例化子类对象 Zi z=new Zi(); z.show(); z.showInfo(30); } }