1、类与对象的初步认知
JAVA是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
面向过程注重的是过程,在整个过程中所涉及的行为,就是功能。
面向对象注重的是对象,也就是参与过程所涉及到的主体。是通过逻辑将一个个功能实现连接起来。
开发时:找对象,建对象,用对象,并维护对象之间的关系。
2、创建类
- 类就是一类对象的统称,对象就是这一类具体化的一个实例
- 类就相当于一个模板,通过这个模板可以实例化多个对象。
// 创建类
class <class_name>{
field;//成员属性
method;//成员方法
}
// 实例化对象
<class_name> <对象名> = new <class_name>();
访问修饰限定符:
- public
- private
- protected
- 默认权限
创建示例:
class Person {
//属性、字段、实例成员变量(定义在类的内部,方法的外部);
public String name;
public int age;
//静态成员变量(存储在方法区),在内存中只有一份
public static int count=10;
//行为、方法、函数
//和之前写的方法不同, 此处写的方法不带 static 关键字
public void eat(){
System.out.println("吃饭");
}
public static void sleep(){
System.out.println("睡觉");
}
对于实例成员变量若未初始化,默认就是其对应的零值: boolean -> false, float->0.0f double->0.0 int,byte,long,short->0 char->'\u0000'
3、类的实例化
- new 关键字用于创建一个对象的实例。
- 使用 . 来访问对象中的属性和方法。
- 静态成员变量(方法)通过类名. 访问(可以不用new对象)。
- 同一个类可以创建多个实例。
public static void main(String[] args) {
Person p=new Person();
//对象:new Person()
//引用:p
//new Person()的过程也叫对象的实例化、实例化了一个对象
//访问形式:通过对象的引用来访问实例成员变量
System.out.println(p.name);//未赋值默认为null
System.out.println(p.age);//未赋值默认为0
// 静态成员变量(方法)通过类名.访问
System.out.println(Person.count);
p.eat();
Person.sleep();
}
重写toString方法 :
public class Test{
public static void main(String[] args) {
Person p=new Person();
p.name="obj";
p.age =10;
System.out.println(p);
}
}
class Person {
public String name;
public int age;
//重写toString方法
// alt+insert
@Override//一种注解,代表以下方法是重写的
public String toString() {
return "Person{" +
"姓名='" + name + '\'' +
", 年龄=" + age +
'}';
}
}
//运行结果:Person{姓名='obj', 年龄=10}
static关键字
1、修饰 成员变量(类变量)
- 访问形式:类名 . 静态成员变量
- 内存存储方式:方法区
- 特点:静态的成员变量只有一份且不依赖对象
2、修饰方法
- 访问形式:类名 . 方法名( )
- 特点:在静态方法方法内部不可以访问实例成员变量
3、代码块
4、修饰类
1、修饰 成员变量
public class Test{
public static void main(String[] args) {
Person p1=new Person();
p1.size++;//1
Person p2=new Person();
p2.size++;//1
Person p3=new Person();
p3.size++;//1
System.out.println(p3.size);
}
}
class Person {
public static int count;
public int size;
}
运行结果:1
public class Test{
public static void main(String[] args) {
Person p1=new Person();
p1.count++;//1
Person p2=new Person();
p2.count++;//2
Person p3=new Person();
p3.count++;//3
System.out.println(p3.count);
}
}
class Person {
public static int count;
public int size;
}
运行结果:3
- 静态成员变量还是用类名加点访问,这里会警告,但不会报错,上边写法是为了对比效果, 也可写作如下,可以不用去实例化对象了。
public class Test{
public static void main(String[] args) {
Person.count++;//1
Person.count++;//2
Person.count++;//3
System.out.println(Person.count);
}
}
class Person {
public static int count;
public int size;
}
2、修饰方法
class TestDemo{
public int a;
public static int count;
public static void change() {
count = 100;
//a = 10; error 不可以访问非静态数据成员
}
}
public class Main{
public static void main(String[] args) {
TestDemo.change();//无需创建实例对象 就可以调用
System.out.println(TestDemo.count);
}
}
//100
总结:
- 总结:所有被static所修饰的方法或者属性,全部不依赖于对象。
- 类变量也叫静态变量,编译时已经产生,属于类本身,且只有一份。存放在方法区。
- 被final修饰的叫常量,也属于对象。 被final修饰,后续不可更改。一个变量放在哪里跟它是否被static修饰有关,和final无关。
public class Test{
public static void main(String[] args) {
//产生对象 实例化对象
Person person = new Person();//person为对象的引用
System.out.println(person.age);//默认值为0
System.out.println(person.name);//默认值为null
System.out.println(Person.count);
System.out.println(Person.COUNT);
Person.staticTest();
//总结:所有被static所修饰的方法或者属性,全部不依赖于对象。
person.eat();
person.sleep();
}
}
class Person {
public int age;//实例变量 存放在对象内
public String name;//实例变量
public static int count;
//类变量也叫静态变量,编译时已经产生,属于类本身,且只有一份。存放在方法区
public final int SIZE = 10;
//被final修饰的叫常量,也属于对象。 被final修饰,后续不可更改
//一个变量放在哪里跟它是否被static修饰有关,和final无关
public static final int COUNT = 99;
//实例成员函数
public void eat() {
int a = 10;//局部变量
System.out.println("eat()!");
}
//实例成员函数
public void sleep() {
System.out.println("sleep()!");
}
//静态成员函数
public static void staticTest(){
//不能访问非静态成员
//sex = "man"; error
System.out.println("StaticTest()");
}
}
4、封装:
把重要的数据和方法用private进行修饰,修饰之后,其权限就变味私有的,也就是只能在类内进行访问。
意义:1、保证数据的安全性
2、类的调用者对类的使用成本降低了
- 此时如果需要获取或者修改这个 private 属性, 就需要使用 getter / setter 方法(Alt+insert) :
- getName 即为 getter 方法, 表示获取这个成员的值,
- setName 即为 setter 方法, 表示设置这个成员的值。
public class Test{
public static void main(String[] args) {
Person person = new Person();
person.setName("Aug");
String name = person.getName();
System.out.println(name);
person.show();
}
}
class Person {
private String name;//实例成员变量
private int age;
public void setName(String name){
//name = name;//不能这样写
this.name = name;//this代表当前对象的引用
}
public String getName(){
return name;
}
public void show(){
System.out.println("name: "+name+" age: "+age);
}
}
name: Aug age: 0
5、构造方法
- 写法:没有返回值,方法名称和类名一样。
- 一个构造函数都未写时,会默认生成一个不带有参数的构造函数,如果你写了构造方法,编译器就不会生成了;
- 构造函数主要是用来构造对象,同时在构造对象的时候可以为对象进行成员的初始化。
实例化一个对象
- 为对象分配内存
- 调用合适的构造方法(不一定只有一个)
如何调用合适的构造方法
- 看对象的参数
public class Test{
public static void main(String[] args) {
Person p1=new Person();
System.out.println();
Person p2=new Person("Aug");
System.out.println();
Person p3=new Person("Aug",3);
}
}
class Person {
private String name;//实例成员变量
private int age;
public void setName(String name){
//name = name;//不能这样写
this.name = name;//this表示当前对象的引用
}
public String getName(){
return name;
}
public void show(){
System.out.println("name: "+name+" age: "+age);
}
//构造方法(重载)
public Person(){
System.out.println("不带有参数的构造方法");
}
public Person(String name){
System.out.println("带有一个参数的构造方法");
}
public Person(String name,int age){
System.out.println("带有2个参数的构造方法");
}
}
//
不带有参数的构造方法
带有一个参数的构造方法
带有2个参数的构造方法
在构造对象的时候可以为对象进行成员的初始化:
public class Test{
public static void main(String[] args) {
Person p3=new Person("Aug",3);
System.out.println(p3);
}
}
class Person {
private String name;//实例成员变量
private int age;
public Person(String name,int age){
//System.out.println("带有2个参数的构造方法");
this.age=age;
this.name=name;
}
//构造函数是用来构造对象的,对象还没有构造好,我们就使用了this,那this还代表当前对象吗?当然不是,this代表的是当前对象的引用。
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
//运行结果:Person{name='Aug', age=3}
this
- this. 可以访问成员变量
- this.可以访问成员方法
- this( )可以调用构造方法(构造方法不可以自己调用自己)
对于 this 和static:
1.静态方法内部不能用 this(原因是静态的不依赖对象),且不能访问非静态的数据。
2.普通的方法内部可以访问静态的数据
3.不管是静态还是非静态的方法,里面都不可以定义静态的变量 (原因是静态的变量属于类不属于方法)。
在一个构造方法内调用另一个构造方法:
public class Test{
public static void main(String[] args) {
Person p=new Person();
}
}
class Person {
private String name;//实例成员变量
private int age;
public Person(){
this("Aug");
System.out.println("无参数");
}
public Person(String name){
System.out.println("一个参数");
}
}
//运行结果:
一个参数
无参数
6、代码块
1.本地代码块
2.示例代码块(构造代码块)
2.静态代码块
4.同步代码块
1.构造代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量
2.静态代码块
使用static定义的代码块。一般用于初始化静态成员属性。
- 静态代码块不管生成多少个对象,其只会执行一次,且是最先执行的。
- 静态代码块执行完毕后, 实例代码块(构造块)执行,再然后是构造函数执行。
class Person{
private String name;//实例成员变量
private int age;
private String sex;
private static int count = 0;//静态成员变量 由类共享数据 方法区
public Person(){
System.out.println("I am Person init()!");
}
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
//静态代码块
static {
count = 10;//只能访问静态数据成员
System.out.println("I am static init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
}
}