构造方法、This关键字、静态与封装的特性与作用
1.构造方法
构造方法是一种特殊的方法,专门用于构造/实例化对象。
构造方法根据是否有参数分为无参构造方法和有参构造方法。
1.1无参构造方法
无参构造方法就是构造方法没有任何参数。无参构造方法在创建(new class类名())时调用;无参构造方法一般用于给属性赋默认值。语法:
[修饰符] 类名(){ ....... }
例如:
public class Dog{ String name;
int health;
int love;
String strain; public Dog(){ //无参构造方法
System.out.println("构造方法");
health = 100; love = 0; } … }
如果开发中没有定义无参构造方法,jvm(虚拟机)默认给类分配一个无参构造方法。
1.2有参构造方法
当构造/实例化对象时,可以向方法中传递参数,这样子构造的方法叫有参构造方法。
语法:
[修饰符] 类名(Type arg1,Type arg2,…){
// 初始化代码
}
注:有参构造方法与无参构造方法是方法重载。
1.2.1有参构造常见的问题
如果一个类中提供了有参构造的方法,则JVM(虚拟机)中就不再给该类分配无参构造。
例如:
public class Dog{
String name;
int health;
int love;
String strain; public Dog(String _name,int _health,int _love,String _strain){ //定义了一个有参构造方法但没有定义无参构造方法
name = _name;
health = _health;
love = _love;
strain = _strain;
}
public class TestCar{
public static void main(String[] args){
Dog dog = new Dog(); //调用无参构造方法
dog.name = name;
dog.health = 100;
dog.love = 0;
dog.strain = strain; }
}
运行结果出错:此时jvm不在默认分配无参构造方法
注意:在开发过程中,如果开发者提供了有参构造方法,一定要习惯性的提供无参构造。
2.This关键字
对象初始化内存图
对象初始化内存图中的方法区位于栈和堆内存的上方,用于保存class和各种方法,对象初始化的过程中最先把class加载该区域,读取class文件中定义的属性和方法,根据定义的属性计算申请内存需要的字节数。
然后用 new在堆中申请内存并初始化内存。并在堆中生成This关键字,This中存放的是该对象本身的地址,也就说当调用This关键字时,还是指向对象本身。this可用于访问本对象属性,同时解决局部变量和成员变量同名的问题(成员变量可以用this.成员变量名代替)。
例如
public Dog2(String name,int health,int love,String strain){
System.out.println("this:"+this);
this.name = name; //this.name代表的就是成员变量(成员属性),name代表的是你输入名。
this.health = health;
this.love = love;
this.strain = strain;
}
通过打印this中的引用,可以看出对象dog和this指向同一内存。
一般而言,dog用于类的外部,this用于类的内部。因为类的内部根本不知道 car 变量名的存在。
方法的调用内存图
因为在方法中调用了该对象的属性,我们可以用This指向该对象,可以更加快捷的找到其属性值。
public void showInfo(){
System.out.print("我的名字叫"+this.name); //this.属性名 访问
System.out.print(",健康值"+this.health);
System.out.print(",亲密度"+this.love);
System.out.println(",我是一只"+this.strain);
}
总结:
[1] this调用属性
[2] this调用方法
[3] this调用本类的构造方法。形如:
public Dog(String name,int health,int love){
this.setName(name); //调用方法
this.setHealth(health);
this.setLove(love);
} public Dog(String name,int health,int love,String strain){
//this.setName(name);
//this.setHealth(health);
//this.setLove(love); // this调用本类的其他构造方法
this(name,health,love); //调用本类的
this.setStrain(strain); // showInfo();
//this.showInfo();
}
3.静态(static)
static 关键字表示静态,可以修饰变量,也可以修饰方法。一个类中包含静态成员(静态变量和静态方法)和实例成员(实例变量也叫属性和实例方法)
下面有这样的一个简单的需求可用static实现
需求:统计汽车工厂生成了多少量车?
ð 统计工厂生成了多少量汽车的功能应该放到类功能上,不应该属于某个对象。
ð 声明一个变量用于统计个数,这个变量应该被类的实例共享。(static)
ð 被类的实例共享的区域在方法区(Car.class)
ð 用static关键字声明这样的变量
public class Car{
String brand;
String type;
4 int price;
static int count; //静态变量的使用方法
public Car(){
count = 0;
} public Car(String brand,String type,int price){
this.brand = brand;
this.type = type;
this.price = price;
count++;
showInfo(); } public void showInfo(){
System.out.println("车辆信息:");
System.out.println("品牌:"+this.brand);
System.out.println("型号:"+this.type);
System.out.println("价格:"+this.price);
System.out.println("我是第"+Car.count+"辆车"); //静态变量的访问方式 }
}
public class TestCar{
public static void main(String[] args){
Car car1 = new Car("奔驰","漏油GL300",66); Car car2 = new Car("奔驰","漏油GL400",66); }
}
从运行效果图可以我们看出定义的静态变量count并属于哪一个对象,他是属于类所有的,类中的所有对象都可以访问。其区别于其它实例变量(brand、type、price)归实例(对象)所有,每个不同的对象都可以赋不同的属性值,各个对象是之间没有什么联系的。下面我们来详细认识什么是静态变量。
3.1静态变量
static 修饰的变量称为静态变量/静态属性,语法:
static 类型 变量名称 [= 初始值]
静态变量归类所有,也叫类变量,分配在方法区(共享区)中的静态区,可以被类的实例(对象)共享访问。
内存图
静态变量的访问方法为:
[1] 类名.静态变量(推荐):更好的说明静态变量归类所有
[2] 对象.静态变量
3.2静态方法
用static修饰的方法我们称为静态方法。使用的语法:
[修饰符] static 返回值类型 方法名(arg…){
}
静态方法也归类所有,调用形式和访问静态变量一样。
[1] 类名.方法名() (推荐)
[2] 对象.方法名()
静态方法在使用过程中遇到的常见问题:
用静态方法访问实例变量
public class Car{
String brand;
String type;
int price;
static int count;
public Car(){
count = 0;
} public Car(String brand,String type,int price){
this.brand = brand;
this.type = type;
this.price = price;
count++;
showInfo(); } public void showInfo(){
System.out.println("车辆信息:");
System.out.println("品牌:"+this.brand);
System.out.println("型号:"+this.type);
System.out.println("价格:"+this.price);
System.out.println("我是第"+Car.count+"辆车");
}
public static int getCarCount(){
//定义一个静态方法访问实例变量
System.out.println("价格:"+this.price);
} }
运行结果:
用静态方法访问实例方法
public static int getCarCount(){
//定义一个静态方法访问实例变量
//System.out.println("价格:"+this.price);
//静态方法访问实例方法
this.showInfo();
}
运行结果:
总结:可以看出通过静态方法并不能访问实例成员(实例变量与实例方法);但是实例方法却可以访问静态成员(静态变量、静态方法);
通过静态方法可以访问静态变量
public static int getCarCount(){
//定义一个静态方法访问实例变量
//System.out.println("价格:"+this.price);
//静态方法访问实例方法
//this.showInfo();
//返回一个静态变量count
return Car.count; }
public class TestCar{
public static void main(String[] args){
Car car1 = new Car("奔驰","漏油GL300",66); Car car2 = new Car("奔驰","漏油GL400",66);
System.out.println(Car.getCarCount()); //调用静态方法并把返回值打印出来 }
}
运行结果:
3.3静态常量
在程序运行过程中,如果一个量的值不会发生改变,可以把该量声明为静态常量,用static final修饰。
public class Penguin{ private String name;
private int health;
private int love;
private String gender; static final String SEX_MALE = "雄";
static final String SEX_FEMALE = "雌"; ....
}
作用:方便日后修改代码,减少重复操作。
4.类的加载机制
为什么:[1]实例方法可以访问静态成员。
[2]静态方法不能访问非静态成员。
当实例化一个对象时(Car car = new Car(…);)jvm首先把Car.class加载到方法区,然后
[1]读取Car.class 根据声明的成员变量计算申请内存需要的字节数
[2]读取Car.class 中的静态成员,给静态变量在方法区分配空间并初始化。
接着new Car 申请内存得到一个car对象,此时才有对象的空间。showInfo才可以通过car对象调用。
也就是说程序运行时是先给静态变量分配空间初始化,那时的对象还没在堆中分配有空间(通俗来说还没产生对象),这时怎么可能调用呢!
5.小结
6.封装
封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
封装的步骤:
[1]属性私有化
[2]提供公共的设置器和访问器
[3]在设置器和访问器中添加业务校验逻辑
public class Penguin{
String name;
// 【1】private 私有的,对外不可见
private int health;
int love;
String gender;
// 【2】提供公共的设置器(setter)和访问器(getter)
public void setHealth(int health){
// 【3】逻辑校验
if(health <0){
this.health = 60;
System.out.println("健康不合法");
}else{
this.health = health;
}
}
public int getHealth(){
return this.health;
} public Penguin(){ }
public Penguin(String name,String gender){
this.name = name;
this.gender = gender;
}
public Penguin(String name,String gender,int health,int love){
this(name,gender);
this.setHealth(health);
this.love = love;
} public void showInfo(){
System.out.print("我的名字叫"+this.name);
System.out.print(",健康值"+this.health);
System.out.print(",和主人的亲密度"+this.love);
System.out.println(",性别"+this.gender); }
}
public class Test01{
public static void main(String[] args){
//new 得到构造方法(调用构造方法)
// Penguin penguin = new Penguin("美美","Q妹");
//penguin.showInfo();
Penguin penguin02 = new Penguin("壮壮","Q仔",-10,10);
penguin02.showInfo();
//Penguin penguin03 = new Penguin();
//penguin03.setHealth(-10);
//penguin03.showInfo();
}
}
运行结果:
从打印结果可以看出,当你输入的健康值小于0时,经过你设定的逻辑校验时,会重新分配默认60。
构造方法、This关键字、静态与封装的特性与作用的更多相关文章
- 如何在Javascript中利用封装这个特性
对于熟悉C#和Java的兄弟们,面向对象的三大思想(封装,继承,多态)肯定是了解的,那么如何在Javascript中利用封装这个特性呢? 我们会把现实中的一些事物抽象成一个Class并且把事物的属性( ...
- python 3全栈开发-面向对象之绑定方法(classmethod与staticmethod的区别)、多态、封装的特性property
一.面向对象绑定方法 一.类中定义的函数分成两大类 1.绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入): 1. 绑定到类的方法:用classmethod装饰器装饰的方法. 为类量身定制 ...
- Java面向对象-构造方法,this关键字
Java面向对象-构造方法,this关键字 构造方法 概念:构造方法是一个特殊的方法,这个特殊方法用于创建实例时执行初始化操作: 上代码: package com.java1234.chap03.se ...
- 084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字
084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字 本文知识点:构造方法-this关键字 说明:因为时间紧 ...
- 面试官:volatile关键字用过吧?说一下作用和实现吧
volatile 可见性的本质类似于CPU的缓存一致性问题,线程内部的副本类似于告诉缓存区 面试官:volatile关键字用过吧?说一下作用和实现吧 https://blog.csdn.net/ ...
- java:构造方法:无参构造/有参构造 this static关键字 静态变量 静态方法 代码块 封装 静态常量。
/*构造方法是一种特殊的方法,专门用于构造/实例化对象,形式:[修饰符] 类名(){ }构造方法根据是否有参数分为无参构造和有参构造*/public class Dog { ...
- JAVASE(七)面向对象:封装性(特性之一)、构造器、属性、关键字
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.封装性 1.为什么要使用封装性? 创建对象以后,可以通过对象.属性名的方法进行赋值.只能限制数据的类 ...
- Python编程-多态、封装、特性
一.多态与多态性 1.多态 (1)什么是多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 序列类型有多种形态:字符串,列表,元组. 动物有多种形态:人,狗,猪 文 ...
- JAVA基础复习与总结<二>构造方法_static关键字_final关键字
构造方法详解 构造器也叫做构造方法(constructor),用于对象的初始化. class Person2 { String name; int age; public Person2(String ...
随机推荐
- Loadrunner 11 中Run-Time Setting详细参数说明
.General/Run Logic :用来设置运行脚本迭代的次数,迭代次数只对run部分的脚本迭代次数有影响,对init和End部分无印象.一般设置未1~3次,只会影响在单位时间内客户端想服务器提交 ...
- 找jar包的网站 还没用过2017.12.19
http://www.findjar.com/index.x http://mvnrepository.com/这个比较好用
- 你不知道的JavaScript--Item27 异步编程异常解决方案
1.JavaScript异步编程的两个核心难点 异步I/O.事件驱动使得单线程的JavaScript得以在不阻塞UI的情况下执行网络.文件访问功能,且使之在后端实现了较高的性能.然而异步风格也引来了一 ...
- [爬虫]BeautifulSoup4
1.Beautiful Soup的简介 Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.python式的函 ...
- bzoj3534 [Sdoi2014]重建
变形的$Martix-Tree$定理 发现我们要求的是$\prod_{i \in E}{p_{i}} * \prod_{i \notin E}{(1-p_{i})}$ 然后呢? 矩阵树对重边也有效对吧 ...
- 毕业样本=[威尔士大学毕业证书]UWIC原件一模一样证书
威尔士大学毕业证[微/Q:2544033233◆WeChat:CC6669834]UC毕业证书/联系人Alice[查看点击百度快照查看][留信网学历认证&博士&硕士&海归&am ...
- Python多版本管理-pyenv
经常遇到这样的情况: 系统自带的Python是2.x,自己需要Python 3.x,此时需要在系统中安装多个Python,但又不能影响系统自带的Python,即需要实现Python的多版本共存,pye ...
- 带你由浅入深探索webpack4(一)
相信你或多或少也听说过webpack.gulp等这些前端构建工具.近年来webpack越来越火,可以说成为了前端开发者必备的工具.如果你有接触过vue或者react项目,我想你应该对它有所了解. 这几 ...
- Itest(爱测试),最懂测试人的开源测试管理软件隆重发布
测试人自己开发,汇聚10年沉淀,独创流程驱动测试.度量展现测试人价值的测试协同软件,开源免费 官网刚上线,近期发布源码:http://www.itest.work 在线体验 http://www. ...
- Vue2.0源码阅读笔记(三):计算属性
计算属性是基于响应式依赖进行缓存的,只有在相关响应式依赖发生改变时才会重新求值,这种缓存机制在求值消耗比较大的情况下能够显著提高性能. 一.计算属性初始化 Vue 在做数据初始化时,通过 in ...