1.类与对象
面向对象中,整个程序的基本单位是类,方法是从属于类
1.1类与类的声明
面向对象的编程语言将客观事物看作具有状态和行为的对象,通过抽象找出同一类对象的共同状态(静态特征)和行为(动态特征),构成模型。
那么如何声明一个类呢?
栗子:
class Person{
String name;
int age;
double weight;
double height;
String hobbies;
//静态数据
void say(String str){
System.out.println(str);
}
//动态行为
}
1.2什么是对象
对象是类的实例,也叫实例对象
那么如何创建一个对象呢?如何调用一个对象的方法呢?
public class Test{
public static void main(String[] args]{
Person p = new Person();
p.say("小青春是一个很棒很棒的男生!!");
//这里用new 就是创建一个对象。
//数组的时候我们也用到了new,之前就想说数组也是对象。
//这里调用say方法来调用对象的行为
}
}
1.3构造函数
1.3.1默认构造函数
上面new 就是调用类的默认构造函数
我们前面博文的案例提到过
1.3.2带参构造函数
String str =new String("xiaoqingchun");
这个就是调用String类的带参构造函数。那如何定义一个带参构造函数呢?
class Person {
String name;
int age;
double weight;
double height;
String hobbies;
// 静态数据
// 动态行为
void say(String str) {
System.out.println(str);
}
Person(String mname,int mage,double mweight,double mheight,String mhobbies) {
name =mname;
age=mage;
weight=mweight;
hobbies=mhobbies;
}
}
public Test{
public static void main(String[] args) {
Person p = new Person("小青春", 260, 120, 160, "football、study、");
p.say("小青春是一个很棒很棒的男生");
}
}
但是如果我们定义了有参数的Constuctor,调用的时候却想调用无参的Constuctor会出现什么问题呢。
鼠标放到提示叉叉地方也能看到编译器给我们的错误提示,你按ctrl+1,eclipse会给你提供相应的供参考的解决方案
a.添加传入参数匹配响应的Constuctor
b.修改Constuctor成无参的Constuctor
3.创建无参的Constuctor
2.this指针
Person(String mname,int mage,double mweight,double mheight,String mhobbies) {
name =mname;
age=mage;
weight=mweight;
hobbies=mhobbies;
}
但如何我希望形参的名字和成员变量的名字一样呢)
如下图,编译器给了警告The assignment to variable name has no effect
我们发现调用该构造函数的时候,并没有给相应的成员变量成功赋值,为什么会无效呢,因为两个重名,编译器不知道那个name是形参,哪个name是成员变量
这个时候仍然可以按ctrl+1,看eclipse提供的方案
一种是修改左边,带this,另一个是修改右边带this
Person(String name,int age,double weight,double height,String hobbies) {
this.name =name;
this.age=age;
this.weight=weight;
this.hobbies=hobbies;
}
概念上来说this对象,我们可以用它在类里面来引用这个类的属性和方法。
2.1 使用this来调用类的普通方法与成员变量
既然如此我们试下使用this来调用类的普通方法与成员变量
void say(String str) {
System.out.println(str);
}
//添加新的代码
void sayHello(String someBody){
this.say(this.name+"对"+someBody+"说:\"你好\" " );
}
2.2 使用this来调用类的构造方法
我们对原来的构造函数进行修改,比如说小青春不想暴露自己的身高体重和兴趣爱好。只告诉你姓名和年龄。
于是我们为他定制了一个函数
Person(String name,int age,double weight,double height,String hobbies) {
//this.name =name;
//this.age=age;
//现在这两句可以用this来调用下面的构造函数
this(name,age);
this.weight=weight;
this.hobbies=hobbies;
}
Person(String name,int age){
this.name =name;
this.age=age;
}
那既然可以代替,那我们是否能把this往后调,放到最后调用?
显然是不行的。
注:在一个构造函数中,构造函数的调用必须是第一个语句
总结一下:
a.this 关键字是类内部当中对自己的一个引用,可以方便类中方法访问自己的属性;
b.可以返回对象的自己这个类的引用,同时还可以在一个构造函数当中调用另一个构造函数。
3.包裹类型
对于基本数据类型,Java提供了对应的包裹(wrap)类型。这些包裹类型将一个基本数据类型的数据转换成对象的形式,从而使得它们可以像对象一样参与运算和传递。
基本类型 | 包裹类型 |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
注:除了int和char以外,包裹类型就是把基本类型的名字的第一个字母大写。在Java的系统类库中,所有第一个字母大写的,都是类的名字。所以在编辑程序的时候,一定要小心大小写,以免一不小心犯错。
3.1装箱与拆箱
装箱:就是将基本数据类型封装成一个对象。
Integer i = 10; //自动装箱
Integer ii = Integer(10);
Integer ii = Integer(10);
拆箱:就是将包裹类型的对象转换成基本数据类
Integer i = 10;
int ii = i; //自动拆箱
int ii = (int)i;
3.2包裹类型的用处
获得该基本数据类型的最大值和最小值
Integer.MIN_VALUE
Integer.MAX_VALUE
Character
静态函数 | 功能 |
---|---|
boolean isDigit(char ch) | 判断该字符是否为数字 |
boolean isLetter(char ch) | 判断该字符是否为字母 |
boolean isLetterOrDigit(char ch) | 判断该字符是否为数字或字母 |
boolean isLowerCase(char ch) | 判断该字符是否为小写字母 |
boolean isUpperCase(char ch) | 判断该字符是否为大写字母 |
boolean isWhiteCase(char ch) | 判断该字符是否为空格 |
char toLowerCase(char ch) | 把该字符转换成小写 |
char toUpperCase(char ch) | 把该字符转换成大写 |
4.包的概念
包就是Java的类库管理机制,它借助文件系统的目录来管理类库,一个包就是一个目录,一个包内的所有的类必须放在一个目录下,那个目录的名字必须是包的名字。
4.1编译单元与类空间
编译单元:一个.java文件就是一个编译单元
1.编译单元中可以有且只有一个public类,作为外界访问该类的接口,且该类的名称必须与文件名称一样。
2.编译单元中可以没有public类,但必须有一个类名称与文件名称相同(但外部不可及,没有意义)。
3.编译单元中可以有一些额外的类,这些类在包访问权限的。
4.2定义包与导入包
package com.xiaoqingchun.server; //定义包,通常包名是以域名倒拼开始的
import java.util.Scanner;//导入util包下的Scanner类
那么如何用javac编译带包定义的代码呢?
package com.xiaoqingchun.test;
class Test {
public static void main(String[] args) {
System.out.println("test");
}
}
那么我们怎么运行呢
1.首先创建一个/com/xiaoqingchun/test层级的目录,然后把Test.class拷贝进去
2.如下图,运行C:\Users\jiaye\Desktop\test>java com.xiaoqingchun.test.Test
每次都要手动去新建目录拷贝多麻烦,javac 给我们提供了一个参数可以直接生成好
命令如下:C:\Users\jiaye\Desktop\test>javac Test.java -d .\
-d也可以往前提
C:\Users\jiaye\Desktop\test>javac -d .\ Test.java
这里注意点,一个类的完成名称是报名.类名。如果要导入另外一个类,那么这个类必须是public权限。如果想访问某些成员变量或成员函数,也必须是public权限。
4.3.静态导入
使用静态导入可以使被导入类的静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。(但是不建议这么做)
import static 包名.类名.静态成员变量(或方法名);
缺点:过度地使用静态导入会在一定程度上降低代码的可读性。
5.访问控制权限
封装,就是把数据和对这些数据的操作放在一起,并且用这些操作把数据掩盖起来,是面向对象的基本概念之一,也是最核心的概念。
如何保证在类的设计的时候做到封装:
1.所有的成员变量必须是private的,这样就避免别人任意使用你的内部数据;
2.所有public的函数,只是用来实现这个类的对象或类自己要提供的服务的,而不是用来直接访问数据的。除非对数据的访问就是这个类及对象的服务。简单地说,给每个成员变量提供一对用于读写的get/set函数也不是不合适的设计
父类成员访问属性 | 在父类中的含义 | 在子类中的含义 |
---|---|---|
public | 对所有人开放 | 对所有人开放 |
protected | 只有包内其它类、自己和子类可以访问 | 只有包内其它类、自己和子类可以访问 |
default | 只有包内其它类可以访问 | 如果子类与父类在同一个包内:只有包内其它类可以访问,否则:相当于private,不能访问 |
private | 只有自己可以访问 | 不能访问 |
6.类变量与类方法(静态变量与静态方法)
1.类是描述,对象是实体。在类里所描述的成员变量,是位于这个类的每一个对象中的。
2.如果某个成员有static关键字做修饰,它就不再属于每一个对象,而是属于整个类的了。
3.通过每个对象都可以访问到这些类变量和类函数,但是也可以通过类的名字来访问它们。
4.类函数由于不属于任何对象,因此也没有办法建立与调用它们的对象的关系,就不能访问任何非static的成员变量和成员函数了。
问:在类函数中有this吗?为什么?
Cannot use this in a static context。不能在静态去使用this。因为类函数是输入类。
注
1.不能在静态方法内访问静态变量
Cannot make a static reference to the non-static field test
2.非静态方法可以访问静态成员变量
7.代码块、构造代码块、静态代码块
我 们说大括号{}定界的代码称为一个代码块,在代码块内部声明的变量,变量的作用域就是这个代码块。
那如果我们把代码块写在构造方法前面(如图),我们把这个代码块称为构造代码块。图上我们可以知道构造代码块优于构造函数的执行。
如果在代码块的前面加上static关键字就变成了静态代码块了,静态代码块在类加载的时候运行。