第二章第三节 面向对象进阶
前言
# 第三章第3节 面向对象进阶
封装
package day01;
public class Demo4 {
public static void main(String[] args){
Person9 p = new Person9();
p.name = "张三";
//程序的逻辑错误
p.age = -10000;
p.say();
}
}
class Person9{
int age;
String name;
void say() {
System.out.println("自我介绍: 姓名: "+name+" ,年龄: "+age);
}
}
封装:
保护或者防止代码(数据)被
private私有在{}中,别人不能操作
package day01;
public class Demo4 {
/**
* 封装
* 不合理的程序,修改后的在
* 要与内部变量(private)联系,需要通过方法去传递参数给内部变量(private)
* 且该方法的参数要设定逻辑范围,去解决逻辑错误
* @param args
*/
public static void main(String[] args){
Person9 p = new Person9();
p.name = "张三";
p.setAge(-100);
p.say();
}
}
class Person9{
//private成员变量让用户无法操作,然后提供setAge方法给用户操作
//setAge设定操作范围
private int age;
String name;
void setAge(int age2) {
if(age2 < 0 || age2 > 150) {
System.out.println("年龄不合理, 自动设置为1");
age = 1;
}else {
age = age2;
}
}
int getAge() {
return age;
}
void say() {
System.out.println("自我介绍: 姓名: "+name+" ,年龄: "+age);
}
}
setAge(-100);
setAge(100);
this关键字
这段代码自己复制给自己有坑
这个才是传递给private的变量
this指的是当前对象,this是被省略的
package day01;
public class Demo3 {
public static void main(String[] args) {
Person11 p1 = new Person11("张三",18);
Person11 p2 = new Person11("李四",18);
p1.say();
p2.say();
}
}
class Person11{
private String name;
private int age;
Person11(){}
Person11(String name,int age){
this.name = name;
this.age = age;
}
void say() {
System.out.println("姓名: "+name+" ,年龄: "+age);
}
}
package day01;
public class Demo3 {
public static void main(String[] args) {
Person11 p1 = new Person11("张三",18);
Person11 p2 = new Person11("李四",18);
p1.say();
p2.say();
}
}
class Person11{
private String name;
private int age;
Person11(){}
Person11(String name,int age){
this.name = name;
this.age = age;
}
void say() {
//这里的this只是被省略了
//调用p1.say()时,this就是p1
//调用p2.say()时,this就是p2
System.out.println("姓名: "+this.name+" ,年龄: "+this.age);
}
}
package day01;
public class Demo3 {
public static void main(String[] args) {
Person11 p1 = new Person11("张三",18);
Person11 p2 = new Person11("李四",18);
p1.say();
p2.say();
Person11 p3 = new Person11();
p3.say();
}
}
class Person11{
private String name;
private int age;
//Person11()是最后使用的,但是this不能在System.out.println后面
Person11(){
this("默认姓名",1);
}
Person11(String name,int age){
this.name = name;
this.age = age;
}
void say() {
//这里的this只是被省略了
System.out.println("姓名: "+this.name+" ,年龄: "+this.age);
}
}
构造方法的作用:构建对象
静态static
package day01;
/**
* static关键字
* @author jiajun.lin
*
*/
public class Demo2 {
public static void main(String[] args) {
//四个北京有点浪费空间
Emp e1 = new Emp("张三","北京");
Emp e2 = new Emp("李四","北京");
Emp e3 = new Emp("王二","北京");
Emp e4 = new Emp("麻子","北京");
//假设, 公司迁址, 天津
e1.setRegion("天津");
e2.setRegion("天津");
e3.setRegion("天津");
e4.setRegion("天津");
//
e1.say();
e2.say();
e3.say();
e4.say();
}
}
class Emp{
private String name;
private String region;//地区
Emp(String name,String region){
this.name = name;
this.region = region;
}
//使用快捷键创建下面
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
//say()
void say() {
System.out.println("员工姓名: "+name+", 员工所在地区: "+region);
}
}
有点费空间呀
改进下
将空间节省下:
static 静态属性
类第一次被使用就会被加载到方法区中
可以这样认为:汽车的图纸,使用次数就是static属性
对象创建多少个,使用了static,那么类只有一个
其实是将对象的属性,换成了类的属性,从而达到减少空间的使用
package day01;
/**
* static关键字
* @author jiajun.lin
*
*/
public class Demo2 {
public static void main(String[] args) {
//类中唯一的属性
Emp.region = "北京";
//四个北京有点浪费空间
Emp e1 = new Emp("张三");
Emp e2 = new Emp("李四");
Emp e3 = new Emp("王二");
Emp e4 = new Emp("麻子");
//
e1.say();
e2.say();
e3.say();
e4.say();
System.out.println("--------------");
//假设, 公司迁址, 天津
Emp.region = "天津";
e1.say();
e2.say();
e3.say();
e4.say();
}
}
class Emp{
//这个是在类(图纸)上,自己再来设计的属性,而非类本身的属性
private String name;
//region 使用静态属性,有自己的内存地址,相当于类(图纸)自身已经定义好的属性
static String region;//地区
Emp(String name,String region){
this.name = name;
this.region = region;
}
//传递
Emp(String name){
this.name = name;
}
Emp(){}
//使用快捷键创建下面
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
//say()
void say() {
System.out.println("员工姓名: "+name+", 员工所在地区: "+region);
}
}
思考创建多少个对象
package day01;
/**
* static关键字
* @author jiajun.lin
*
*/
public class Demo3 {
public static void main(String[] args) {
//类中唯一的属性
Emp.region = "北京";
//四个北京有点浪费空间
Emp e1 = new Emp("张三");
Emp e2 = new Emp("李四");
Emp e3 = new Emp("王二");
Emp e4 = new Emp("麻子");
//
e1.say();
e2.say();
e3.say();
e4.say();
System.out.println("--------------");
//假设, 公司迁址, 天津
Emp.region = "天津";
e1.say();
e2.say();
e3.say();
e4.say();
System.out.println(Emp.count);
Emp e = new Emp();
System.out.println(Emp.count);
}
}
class Emp{
//这个是在类(图纸)上,自己再来设计的属性,而非类本身的属性
private String name;
//region 使用静态属性,有自己的内存地址,相当于类(图纸)自身已经定义好的属性
static String region;//地区
//使用count来展示创建多少个对象
static int count;
Emp(String name,String region){
count++;
this.name = name;
this.region = region;
}
//传递
Emp(String name){
count++;
this.name = name;
}
Emp(){
count++;
}
//使用快捷键创建下面
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
//say()
void say() {
System.out.println("员工姓名: "+name+", 员工所在地区: "+region);
}
}
使用类的方法,静态资源可被调用的时机早于动态
package day01;
public class Demo2 {
public static void main(String[] args) {
StaticDemo.say();
}
}
class StaticDemo {
/**
* 静态修饰的方法, 被调用时, 有可能对象还未被创建
*/
static void say() {
System.out.println("锄禾日当午,汗滴禾下土");
}
}
package day01;
public class Demo2 {
public static void main(String[] args) {
StaticDemo.say();
}
}
/**
* 在访问时,静态不能访问非静态, 动态可以调用静态
* 即: 类不能使用对象的创建的方法, 而对象可以使用类创建的方法
* 可以这样说过去的人不可能使用现在人所使用的高科技,但现在的人却可以使用过去人所使用的火种
* @author jiajun.lin
*
*/
class StaticDemo {
/**
* 静态修饰的方法, 被调用时, 有可能对象还未创建
* 类来调用的
*/
static void say() {
System.out.println("锄禾日当午,汗滴禾下土");
}
/**
* 通过对象来调用的
*/
void say2() {
System.out.println("床前明月光");
}
}
包
不要使用默认包
包的命名规范:
多个单词组成,每个单词所有字母全部小写,单词与单词使用.隔开
例: com.公司名.项目名.模块名…
多种层次的文件夹
两个文件夹在同一层
如果要使用到别的类,就需要导包
import
package com.kakaba.demo1;
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
}
}
或者写上类的全名称
package com.kakaba.demo1;
//import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
//类的全名称
java.util.Scanner input = new java.util.Scanner(System.in);
}
}
包2
有些类不需要导入,是因为存储在java.lang中
还有一种不需要导包,就是在同一级的类
package com.kakaba.demo1;
public class Demo2 {
public static void main(String[] args) {
String text = "123123";
}
}
权限修饰符
public,protected,default,private
用的最多的是public,private
资源跨包的使用
代码块
类的代码块
方法的代码块
普通的代码块
构造的代码块
package com.kakaba.demo1;
public class Demo2 {
//类的代码块
public static void main(String[] args) {
//方法的代码块
{//普通代码块
/**
* 编写在顺序执行的代码该流程中的代码块
*/
int a = 10;
System.out.println(a);
}
}
}
class Person{
//构造代码块
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.kakaba.demo1;
public class Demo2 {
//类的代码块
public static void main(String[] args) {
//方法的代码块
{//普通代码块
/**
* 编写在顺序执行的代码该流程中的代码块
*/
//int a = 10;
// System.out.println(a);
}
Person p = new Person();
}
}
class Person{
//构造代码块
private String name;
private int age;
{//构造代码块
System.out.println("对象创建时执行1");
}
public Person() {
System.out.println("对象创建时执行2");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
void say() {
System.out.println("姓名: "+name+",年龄: "+age);
}
}
多个对象创建
package com.kakaba.demo1;
public class Demo2 {
//类的代码块
public static void main(String[] args) {
//方法的代码块
{//普通代码块
/**
* 编写在顺序执行的代码该流程中的代码块
*/
//int a = 10;
// System.out.println(a);
}
Person p1 = new Person();
Person p2 = new Person();
}
}
class Person{
//构造代码块
private String name;
private int age;
/**
* 构造代码块, 随着对象的每次创建, 执行一次, 且执行在构造方法之前.
*/
{//构造代码块
System.out.println("对象创建时执行1");
}
public Person() {
System.out.println("对象创建时执行2");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
void say() {
System.out.println("姓名: "+name+",年龄: "+age);
}
}
面试题目:
构造方法与 构造代码块 以及 静态代码块的顺序:
静态代码块-> 构造代码块 -> 构造方法
package com.kakaba.demo1;
public class Demo2 {
//类的代码块
public static void main(String[] args) {
//方法的代码块
{//普通代码块
/**
* 编写在顺序执行的代码该流程中的代码块
*/
//int a = 10;
// System.out.println(a);
}
Person p1 = new Person();
Person p2 = new Person();
}
}
class Person{
//构造代码块
private String name;
private int age;
/**
* 构造代码块, 随着对象的每次创建, 执行一次, 且执行在构造方法之前.
*
* 区别于构造方法的是:
* 无论用户调用哪一个构造方法来创建对象, 构造代码块都必然执行
*/
{//构造代码块
System.out.println("对象创建时执行1");
}
/**
* 静态代码块, 随着类的加载 (第一次使用), 静态代码块执行.
* 因为类只加载一次, 所以静态代码块只执行一次
* 例子:给用户发短信,和验证码
* 准备唯一资源就放到静态代码块,资源不会被重复加载进来
*/
static {
System.out.println("静态代码块执行");
}
public Person() {
System.out.println("对象创建时执行2");
}
//
public Person(String name) {
System.out.println("对象创建时执行2");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
void say() {
System.out.println("姓名: "+name+",年龄: "+age);
}
}
main方法详解