本章属于面向对象第二章的内容,主要讲解this关键字、static关键字、代码块、package、import、面向对象三大特征之一---封装等知识点。
public class TestThis {
int a,b,c;
TestThis(){
System.out.println("正要new一个Hello对象");
}
TestThis(int a,int b){
//Hello();// //这样是无法调用构造方法的!
this(); //调用无参的构造方法,并且必须位于第一行!
a = a;//这里都是指的局部变量而不是成员变量
this.a = a;//这样就区分了成员变量和局部变量. 这种情况占了this使用情况的大多数!
this.b = b;
}
TestThis(int a,int b,int c){
this(a,b);//调用无参的构造方法,并且必须位于第一行!
this.c = c;
}
void sing(){
}
void chifan(){
this.sing();//sing();
System.out.println("你妈妈喊你回家吃饭!");
}
public static void main(String[] args){
TestThis hi = new TestThis(2,3);
hi.chifan();
}
}
6. 课堂demo【重点掌握】
package netclass02;
/**
* @Auther: Yu Panpan
* @Date: 2022/1/7 - 01 - 07 - 14:24
* @Description: netclass02
* @version: 1.0
*/
/*
* this:表示当前对象的指针
* 指向当前对象,表示当前对象的引用
* 用途:
* 1、构造方法,当构造方法中的参数名称跟类的成员变量名称一样的时候,可以使用this代表当前对象
* 注意:有了this之后,就可以将构造方法的参数跟成员变量保持一致(符合命名规范)
* 当构造方法中需要调用其他的构造方法时,可以使用this(参数列表)调用其他构造方法,但是必须位于方法体的第一行(规则)
* 2、普通方法中:
* 当多个普通方法之间需要相互调用的时候,可以使用this来进行调用,指的是当前对象的其他方法
* 3、调用成员变量的时候如何使用:
* 当方法中的参数名称跟成员变量保持一致的时候,使用 this.变量名称 表示的是对象的值,而使用变量名称表示形参列表中的值
*/
public class ThisDemo {
//成员变量
String name;
int age;
//构造器、构造方法
public ThisDemo(){
}
public ThisDemo(String name){
this.name = name;
}
public ThisDemo(String name,int age){
// this.name = name;
this(name);
this.age = age;
}
public void test1(){
System.out.println("test1被执行");
// test2(); //也可以省略this来调用其他方法
}
public void test2(String name){
System.out.println("test2被执行");
this.test1();
System.out.println(name);
System.out.println(this.name);
}
public static void main(String[] args) {
ThisDemo td = new ThisDemo("张飞",20);
// System.out.println(td.name);
// System.out.println(td.age);
// td.test1();
td.test2("赵云");
}
}
public class TestStatic {
int a;
static int width;
static void gg(){
System.out.println("gg");
}
void tt(){
System.out.println("tt");
}
public static void main(String[] args){
TestStatic hi = new TestStatic();
TestStatic.width = 2;
TestStatic.gg(); //gg();
//通过引用也可以访问static变量或static方法。不过,一般还是使用类名.static成员名来访问。
hi.gg();
gg();
}
}
package netclass02;
/**
* @Auther: Yu Panpan
* @Date: 2022/1/7 - 01 - 07 - 15:17
* @Description: netclass02
* @version: 1.0
*/
/*
* 使用static统计在类中一共产生多少个对象?
*/
public class StaticDemo2 {
static int count;
// int count;
public StaticDemo2(){
count++;
System.out.println("创建了" +count + "个对象");
}
public static void main(String[] args) {
new StaticDemo2();//1
new StaticDemo2();//2
new StaticDemo2();//3
}
}
public void showInfo(){
System.out.println("姓名:"+this.name+"\t年龄:"+this.age+"\t城市:"+this.country);
}
public static void welcome(){
this.showInfo();//调用本类的非静态方法
System.out.println("欢迎大家来腾迅互联学习......");
}
class Dog {
private String name = "旺财"; // 昵称
private int health = 100; // 健康值
private int love = 0;
public void play(int n) {
static int localv=5;//在方法里不可以定义static变量
health = health - n;
System.out.println(name+" "+localv+" "+health+" "+love);
}
public static void main(String[] args) {
Dog d=new Dog();
d.play(5);
}
}
static、非private修饰 | 非static、private修饰 | |
---|---|---|
属性 | 类属性、类变量 | 实例属性、实例变量 |
方法 | 类方法 | 实例方法 |
调用方式 | 类名.属性 类名.方法() 对象.属性 对象.方法() | 对象.属性 对象.方法() |
归属 | 类 | 单个对象 |
11.课堂demo【重点掌握】 |
package netclass02;
/**
* @Auther: Yu Panpan
* @Date: 2022/1/7 - 01 - 07 - 14:46
* @Description: netclass02
* @version: 1.0
*/
/*
* static:
* 修饰成员变量的时候,表示静态成员变量或者叫类变量
* 普通变量在使用的时候,必须要通过对象名进行调用
* 类变量或者静态变量可以使用对象名调用也可以使用类名进行调用
* 修饰方法的时候,表示静态方法或者叫类方法
* 普通方法在使用的时候,必须要通过对象名进行调用
* 类方法或者静态方法可以使用类名,也可以使用对象名
* 注意:
* 1、静态变量,在创建对象之前被初始化,或者说在类被载入之前进行初始化
* 2、静态变量被所有的对象共享,属于公共变量,对象和类都可以直接调用,但是推荐使用类来调用
* 3、成员变量放在堆中,而静态变量放在方法区中的静态区中
* 4、静态变量不能定义在静态方法中
* 5、静态方法可以在非静态方法中进行调用
* 6、静态方法中不能直接调用非静态方法,换句话说可以间接调用非静态方法
* 7、静态方法中不允许出现this调用
* 8、一般工具类中的方法定义为static
*/
public class StaticDemo {
//成员变量
String name = "zhangfei";
static int age = 20; //静态成员变量
// public StaticDemo(String name,int age){
// this.name = name;
// this.age = age;
// }
public void test1(){
System.out.println("test1 is a non-static method");
// static int a = 10;
// test2();
}
public static void test2(){
// this.test1();
System.out.println("test2 is a static method");
// static int a = 10;
// test1();
new StaticDemo().test1(); //间接调用
}
public static void main(String[] args) {
StaticDemo sd = new StaticDemo();
System.out.println(sd.name);
System.out.println(sd.age);
// sd.age = 30;
// System.out.println(sd.age);//30
// System.out.println(sd.age);//30
//
// sd.age = 40;
// System.out.println(sd.age);//40
// System.out.println(StaticDemo.age);//40
StaticDemo staticDemo = new StaticDemo();
staticDemo.test1();
// StaticDemo.test2();
// staticDemo.test2();
// StaticDemo sd2 =new StaticDemo();
// System.out.println(sd2.name);
}
}
public class TestStaticBlock {
static {
System.out.println("此处,可执行类的初始化工作!");
}
public static void main(String[] args) {
System.out.println("main方法中的第一句");
}
}
4. 课堂demo【重点掌握】
package netclass02;
/**
* @Auther: Yu Panpan
* @Date: 2022/1/7 - 01 - 07 - 15:34
* @Description: netclass02
* @version: 1.0
*/
/*
* 代码块: 使用{}括起来的一段代码叫做代码块
* 分类:
* 普通代码块: 定义在方法中,使用{}括起来的代码叫做普通代码块
* 构造代码块:定义在类中的使用{}括起来的代码叫做构造代码块
* 注意:每次代码运行的时候会将构造代码块中的代码添加到构造方法的前面
* 构造代码块中的代码会添加到每一个构造方法中,当使用this(参数)的时候不会添加
* 静态代码块:使用static{}括起来的代码叫做静态代码块,在程序载入的时候优先执行
* 数据库连接等其他提前需要准备好的代码会放在static代码块
* 同步代码块:
* 在使用多线程的时候会使用,用来给共享空间进行加锁操作(后面讲)
* 执行顺序:静态代码块--》构造代码块(创建对象的时候才会用到)--》普通代码块
*/
public class CodeBlockDemo {
int x;
int y;
{
System.out.println("构造代码块");
}
static{
System.out.println("static代码块");
// x = 100;
}
public CodeBlockDemo(){
}
public CodeBlockDemo(int x){
System.out.println("CodeBlockDemo(int x)被执行了");
this.x = x;
}
public CodeBlockDemo(int x,int y){
this(x);
System.out.println("CodeBlockDemo(int x,int y)被执行了");
// this.x = x;
this.y = y;
}
public void test1(){
System.out.println("test1方法被执行");
{
System.out.println("test1方法中的普通代码块");
}
}
public synchronized void test2(){
//定义一个同步代码块(先见个面,讲到多线程的时候再详细讲。)
// synchronized(this){
//
// }
}
public static void main(String[] args) {
CodeBlockDemo cbd = new CodeBlockDemo();
cbd.test1();
{
System.out.println("main方法中的普通代码块");
}
CodeBlockDemo cbd2 = new CodeBlockDemo(1,2);
}
}
package netclass02;
import java.util.Date;
import java.util.Scanner;
/**
* @Auther: Yu Panpan
* @Date: 2022/1/7 - 01 - 07 - 16:24
* @Description: netclass02
* @version: 1.0
*/
/*
* package:包,对应到文件系统就是多级目录
* 为了解决两个问题:
* 1、文件同名问题
* 2、为了方便管理类,将具体处理功能的代码放到同一个目录下
* 使用:
* 一般定义package会放置在java文件的第一行
* package 域名的倒写
* 比如:www.taobao.com
* 包名:com.taobao.
* package com.tensent.项目名称
* 包名的命名规则:
* 企业性质.企业名称.项目名称.模块名称. 子模块名称....
* 企业性质:com org edu gov
* 企业名称:alibaba baidu huawei tensent
* 项目名称:oa erp hrms crm
* 模块名称:ums--userManagementSystem 用户管理系统
* oms--orderManagementSystem 订单管理系统
* pms--productManagementSystem 产品管理系统
* 完整的包名:com.alibaba.taobao.ums/com.alibaba.taobao.oms
* 完全限定名: 包名+类名
*
* JDK中常用的包:
* lang:不需要手动导入,自动加载
* awt: 包含了一些GUI图形界面常用的类(这个现在已经不用了,了解即可)
* util: 工具包
* net: 网络包
* io: 输入输出流包
*
*/
public class PackageDemo {
public static void main(String[] args) {
// java.util.Date date = new java.util.Date();
// java.util.Scanner scanner = new java.util.Scanner(System.in);
Date date = new Date();
Scanner scanner = new Scanner(System.in);
// System.out.println(Math.random());
// System.out.println();
}
}
package netclass02;
import static java.lang.Math.*;
/**
* @Auther: Yu Panpan
* @Date: 2022/1/7 - 01 - 07 - 16:46
* @Description: netclass02
* @version: 1.0
*/
/*
* import:
* 当需要引入非lang包的其他java类的时候,需要使用import工具
* 如果不使用import,每次在使用某个类的时候必须要将类的完全限定名都加上才可以使用,太过于繁琐
*
* 用法:
* import java.包名.类名;导入具体的类 推荐使用
* import 包名.*; 将当前包下的所有类文件都进行导入,不推荐,因为它不会影响运行速度,但是会影响编译的速度
* 注意:
* 当一个java文件中需要使用多个同名的类的时候,只能选择导入一个,另一个使用完全限定名的方式进行导入
*
* 静态导包:
* 当需要使用某个类的多个方法的时候,同时又不想频繁写该类的名称,此时可以使用静态导包
*/
public class ImportDemo {
public void abs(){
}
public static void main(String[] args) {
// Scanner scanner = new Scanner(System.in);
// java.util.Arrays.sort(new int[]{1,3,5,4,2});
//使用netlclass01中的Person类
// Person person = new Person();
// Date date = new Date();
// long time = 12332423;
// java.sql.Date date1 = new java.sql.Date(time);
// System.out.println(Math.random());
// System.out.println(Math.sqrt(4));
// System.out.println(Math.abs(-2));
//静态导包可以省略类名
System.out.println(random());
System.out.println(sqrt(4));
System.out.println(Math.abs(-10));
}
}
Dog d = new Dog();
d.health = -1000;//属性随意访问,不合理的赋值
如何解决上面设计的缺陷?--->使用封装
class Dog {
private String name = "旺财"; // 昵称
private int health = 100; // 健康值
private int love = 0; // 亲密度
private String strain = "拉布拉多犬"; // 品种
public int getHealth() {
return health;
}
public void setHealth (int health) {
if (health > 100 || health <0) {
this.health = 40;
System.out.println("健康值应该在0和100之间,默认值是40");
}
else{
this.health = health;
}
}
// 其它getter/setter方法
7. 课堂demo【重点掌握】
package netclass02;
/**
* @Auther: Yu Panpan
* @Date: 2022/1/7 - 01 - 07 - 17:13
* @Description: netclass02
* @version: 1.0
*/
/*
* 定义类的时候需要包含以下组件:
* 私有属性
* 构造方法(无参构造方法和自定义构造方法)
* set/get方法
* 普通方法
*/
public class Dog {
private String name;
private int age; //私有属性,只能在当前类中调用
private int weight;
public Dog(){
}
public Dog(String name,int age,int weight){
this.name = name;
this.age = age;
this.weight = weight;
}
//定义一个设置年龄的方法
public void setAge(int age){
if(age > 0){
this.age = age;
}else{
System.out.println("您输入的年龄不合法,请重新输入!");
}
}
//定义一个获取年龄的方法
public int getAge(){
return this.age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public void eat(){
System.out.println("eating bones");
}
public void play(){
System.out.println("playing...");
}
public void show(){
System.out.println("name:" +this.name);
System.out.println("age:" +this.age);
System.out.println("weight:" +this.weight);
}
}
测试类
package netclass02;
/**
* @Auther: Yu Panpan
* @Date: 2022/1/7 - 01 - 07 - 17:14
* @Description: com.tensent.test
* @version: 1.0
*/
/*
* 封装:
* 概念:
* 将类的某些信息隐藏在类内部,不允许外部程序直接访问,
* 而是通过该类提供的方法来实现对隐藏信息的操作和访问
* 封装解决什么问题:
* 如果任何一个处理类都可以直接对Dog进行赋值操作,那么当值不准确的时候,可以会产生意想不到的结果,
* 如何在赋值的同时添加一些逻辑判断呢?
* 封装可以解决此问题
* 作用:
* 使用封装可以保证数据的规范,不符合规范的数据将无法进行操作
* 好处:
* 1、隐藏类的内部实现细节
* 2、只能通过提供的方法进行访问,其他方法无法访问
* 3、可以根据需求添加复杂的逻辑判断语句
* 4、方便修改实现
* 面向对象的封装(狭义)可以用一句话概述: 为了保证数据安全和规范
* 将类中的属性设置为私有属性,提供公有的外部方法供程序进行调用,可以实现丰富的细节操作
* 广义的封装:
* 可以将完成特定功能的代码块封装成一个方法,供不同的程序进行调用
*/
public class DogTest {
public static void main(String[] args) {
Dog dog = new Dog();
// dog.name= "wangwang";
// dog.age = -10;
// dog.setAge(20);
// dog.weight = 35;
// dog.show();
dog.setName("wangwang");
dog.setAge(20);
dog.setWeight(35);
System.out.println(dog.getName());
System.out.println(dog.getAge());
System.out.println(dog.getWeight());
}
}
待续......
待续......
类型 | 属性 | 属性 | 属性 | 属性 | 行为 |
---|---|---|---|---|---|
狗 | 昵称 | 健康值 | 亲密度 | 品种 | 输出信息 |
企鹅 | 昵称 | 健康值 | 亲密度 | 性别 | 输出信息 |
– 根据类图编写Dog类和Penguin类 | |||||
– 添加默认构造方法 |
Dog(String name, String strain)
– 修改Test类,使用带参构造方法创建对象