类和对象 (抽象)
OOP语言(object orinented ):面向对象编程
OOP语言三大特征:继承 封装 多态
面向过程:在整个过程中所涉及的行为,就是功能。
面向过程:C 小的问题
面向对象:参与过程中所涉及到的主体就是对象。是通过逻辑将一个个功能实现连接起来。
面向对象:C++ JAVA 问题规模较大的
找对象 创建对象 使用对象
1. 类与对象的初步认知
模板=类
实体=对象
类拥有属性和方法。
- 属性(成员变量):实例数据成员(对象) 静态数据成员
- 方法(成员方法):实例成员方法 静态成员方法
大象🐘
面向过程:1.冰箱打开2.放入冰箱3.冰箱关闭
面向对象:打开冰箱 储存,关闭都是对冰箱的操作,是冰箱的行为。冰箱就是对象,只要操作冰箱所具备的功能,都要定义在冰箱中。
面向对象概念:
面向对象是一个思考方式,是一种思想。
eg:概念与实例,理论与实践,名和实,类和对象。
类是一类对象的统称,对象是这一个类的具体化的一个实例。
面向对象的好处:将复杂的事情简单了 只要面对一个对象就行。
面对对象设计:
被动的一方是数据拥有者,主动的一方是执行者。
开发时:找对象 建对象 用对象 并维护对象之间的关系。
简而言之,面向对象是用代码(类)描述一个事物,包含事物的属性和行为。
2. 类和类的实例化
类 就是一类对象的统称 对象就是这一类具体化的一个实例。
一个类,可以产生无数的对象。
声明一个类就是创建一个新的数据类型,类在JAVA中属于引用类型。
JAVA中用class声明类。
基本语法:
class <class_name>{
field; //成员属性
mothod; //成员方法
}
实例化对象:
<class_name> <对象名>=new <class_name>();
类中元素为成员属性,类中函数为成员方法。
//eg:Person 类
//Person 类函数
class Person{
public int age;
public String name;
public String sex;
public void eat(){ // 函数=成员方法
System.out.println("吃饭!");
}
public void sleep(){
System.out.println("睡觉!");
}
}
类的实例化:
类只是一个模型,定义一个类并没有分配实际的内存空间来存储它。
一个类可以实例化多个对象,实例化出的对象,占用实际的物理空间,存储类成员变量。
//主函数 实例类 对象引用调用成员方法
public static void main(String[] args) {
Person person1=new Person(); //new
person1.eat(); //使用.访问对象中的方法
person1.age=10;
System.out.println(person1.age); //使用.访问对象中的属性
}
new关键字用于创建一个对象的实例。
通过对象使用 . 访问对象中的属性和方法。
person1 . 数据成员 person1 . 方法
同一个类可以创建多个实例。
3.类的成员
类的成员包含:字段、方法、代码块、内部类和接口。
3.1 字段
在类中,但定义在方法外部定义的变量。
用于描述一个类中包含哪些数据。
class Person{
public String name; //字段
public int age;
}
public static void main(String[] args) {
Person person1=new Person(); //new
System.out.println(person1.name);
System.out.println(person1.age);
} //输出null 0
.访问对象字段 _____访问包含读和写
如果没有设置初始值,则被设置为一个默认的初值。
引用(String Array):null char:\u0000 boolean:false
认识null 在Java中为空引用,表示无效的对象。 可理解为空指针。
对null进行. 操作会异常。
class Person{
public String name; //字段
public int age;
}
public static void main(String[] args) {
Person person=new Person();
System.out.println(person.name.length()); //获取字符串长度
}
Exception in thread "main" java.lang.NullPointerException
at test1029.main(test1029.java:17) 报错异常
字段就地初始化:
class Person{
public String name="张欣悦"; //字段
public int age=19;
}
public static void main(String[] args) {
Person person=new Person();
System.out.println(person.name); //张欣悦
System.out.println(person.age); //19
}
3.2 方法
用于描述一个对象的行为。
class Person {
public String name="张欣悦"; //字段
public int age=19;
public void show(){
System.out.println("我叫"+name+",今年"+age+"岁。");
}
}
public static void main(String[] args) {
Person person=new Person();
person.show();
}
我叫张欣悦,今年19岁。
show方法,表示Person有展示自我的行为。
此时show与person相关联,当创建其他实例,show行为会发生变化。
public static void main(String[] args) {
Person person1=new Person();
person1.name="李四";
person1.age=20;
person1.show();
}
我叫李四,今年20岁。
方法中还有一种特殊的方法,称为构造方法。
3.3 static关键字 类名访问静态 一份
修饰属性,修饰方法,代码块,修饰类。
static
class TestDemo {
public int a; 默认为0
public static int count; 默认为0
}
public static void main(String[] args) {
TestDemo t1=new TestDemo();
t1.a++;
TestDemo.count++;
System.out.println(t1.a); 1
System.out.println(TestDemo.count); 1
System.out.println("=============");
TestDemo t2=new TestDemo();
t2.a++;
TestDemo.count++;
System.out.println(t2.a); 1
System.out.println(TestDemo.count); 2
}
Java中静态属性和类相关,和具体实例无关。
同一个类的不同实例共用一个静态属性。 静态属性通过类名访问。
静态的数据成员和方法,不依赖于对象。
static 修饰方法则为静态方法:
静态方法属于类,不属于类的对象。
可直接调用静态方法,不需创建实例。
静态方法内部,不允许访问实例成员变量,不允许调用实例成员方法。
静态方法可以访问静态数据成员,并可以修改静态数据成员的值。
class TestDemo {
public int a;
public static int count;
public static void change(){
count=100;
// a=10; 报错不可调用实例成员变量
}
}
public static void main(String[] args) {
TestDemo.change();;
System.out.println(TestDemo.count);
} //输出100
静态方法中不能使用:
this 是当前实例的引用,super 是当前实例父类的引用。
main方法为static 方法。
小结:
static修饰为静态变量(方法),属于类本身,只有一份,存放在方法区。
final修饰为常量,属于对象,不可修改。
static final 静态的常量,属于类本身,只有一份,不可更改,存放方法区。
类的每一个实例,都放在堆中但互不相干。
4.封装:
两种角色:类的实现者,类的调用者。
封装的本质:让类的调用者不必太多的了解类的实现这是如何实现类的,只要知道如何使用类就可以。
降低了类使用者的学习和使用成本,降低了复杂程度。
4.1private实现封装
public共有,可以被类的调用者使用。
private私有,不能被类的调用者使用。 访问修饰限定符
体现封装性:被private修饰,只能在类内访问调用
class Person {
public String name="张欣悦";
public int age=19;
}
public static void main(String[] args) {
Person person1=new Person();
System.out.println("我叫"+person1.name+",今年"+person1.age+"岁。");
}
我叫张欣悦,今年19岁。
此代码需要类的使用者了解类的内部才能实现。👆👆👆
class Person {
private String name="张欣悦";
private int age=19;
public void show(){
System.out.println("我叫"+name+",今年"+age+"岁。");
}
}
public static void main(String[] args) {
Person person2=new Person();
person2.show();
}
我叫张欣悦,今年19岁。
此代码使用priavte修饰,类的调用者在mian中不能直接调用。👆👆👆
需借助show方法,此时类使用者不必了解类的实现细节。
当类实现者修改了private所修饰的属性,则类调用者不用做任何修改(访问不到)。
private可修饰字段,方法。
通常字段用private修饰,方法用public修饰。(需视情况而定)
4.2getter和setter方法
当属性被private修饰时,在mian中无法调用。
如需获取修改这个private属性,则需要用getter和setter。
class Person {
private String name="张欣悦";
private int age = 19;
public void setName(String name){ //getter方法
// name=name; 报错
this.name=name; //引用,调用该方法的对象
}
public String getName(){ //setter方法
return name;
}
public void show(){
System.out.println("name:"+name+" age:"+age);
}
}
public static void main(String[] args) {
Person person1=new Person();
person1.setName("caocao");
String name=person1.getName();
System.out.println(name);
person1.show();
} 输出: caocao
name:caocao age:19
setter方法:设置这个成员的值。 不使用this等于自赋值,无意义。
getter方法:获取这个成员的值
Alt+Insert 快捷创建 或 鼠标右键Generate
当字段****拥有setter或getter,可称之为属性。
5.构造方法
给数据成员初始化的方式:
1.提供一系列get set 方法
2.构造方法 作用?用来产生对象
构造方法是一种特殊的方法:
使用关键字new实例化对象时会被自动调用,用于完成初始化操作。
new
1.为对象分配空间
2.调用对象的构造方法
class Person {
private String name;
private int age;
private String sex;
public Person(){ //默认构造函数 构造对象
this.name="caocao";
this.age=10;
this.sex="男";
} //含三个参数的构造函数
public Person(String name,int age,String sex){
this.name=name;
this.age=age;
this.sex=sex;
}
public void show(){
System.out.println("name:"+name+" age:"+age);
}
}
public static void main(String[] args) {
Person person1=new Person();
person1.show();
Person person2=new Person("zhangfei",20,"男");
person2.show();
}
输出 name:caocao age:10 name:zhangfei age:20
语法规则:1.方法名必须与类名相同
2.构造方法没有返回值类型声明
3.没一个类中至少存在一个构造方法。
如果程序没有提供任何构造方法,
编译器会默认生成一个 不带有参数的构造方法。
只有一种情况下才会产生,什么构造方法都没有的情况下。
构造方法支持重载,规则与普通方法重载一致。
this关键字
this为当前对象的引用(不是当前对象),可借助this来访问对象的字段和方法。
this.成员变量
this.成员方法
this();调用构造方法
class Person {
private String name;
private int age;
private String sex;
public Person(){
this("zxy",19,"woman");
}
public Person(String name,int age,String sex){
this.name=name;
this.age=age;
this.sex=sex;
}
public void show(){
System.out.println("name:"+name+" age:"+age);
}
}
public static void main(String[] args) {
Person person1=new Person();
person1.show();
}
构造方法 可以发生重载。
函数名相同 参数不同(类型 个数)返回值不做要求
6.代码块:
字段的初始方式:
1.就地初始化
2.使用构造方法初始化
3.使用代码块初始化
代码块:使用{}定义的一段代码。
普通代码块、构造块、静态块、同步代码块。 四种分类
构造代码块{ } 也叫实例代码块。
初始化实例的数据成员 ,优先于构造方法执行的。
class Person{
private String name;//实例成员变量
private int age;
private String sex;
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()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public static void main(String[] args) {
Person p1 = new Person();
p1.show();
}
// 运行结果 先执行实例代码块 在按顺序执行代码
I am instance init()!
I am Person init()!
name: bit age: 12 sex: man
顺序:静态 实例 构造方法
静态代码块 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 static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person(); //静态代码块是否还会被执行?
}
//运行结果
I am static init()!
I am instance init()!
I am Person init()!
I am instance init()!
I am Person init()!
静态代码块不管生成多少个对象,其只会执行一次,且是最先执行的。
静态代码块执行完毕后, 实例代码块(构造块)执行,再然后是构造函数执行。
7.toString方法
示例:
class Person {
private String name;
private int age;
public Person(String name,int age) {
this.age = age;
this.name = name;
}
public void show() {
System.out.println("name:"+name+" " + "age:"+age);
}
}
public static void main(String[] args) {
Person person = new Person("caocao",19);
person.show();
System.out.println(person); //打印的是一个地址的哈希值
//原因:调用的是Object的toString方法
}
//执行结果
name:caocao age:19
Person@1c168e5
使用 toString 这样的方法来将对象自动转成字符串.
示例:
class Person{
private String name;//实例成员变量
private int age;
private String sex;
private static int count = 0;//静态成员变量 由类共享数据 方法区
public Person(String name,int age) {
this.age = age;
this.name = name;
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
//重写Object的toString方法
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public static void main(String[] args) {
Person person = new Person("caocao",19);
person.show();
System.out.println(person);
}
// 执行结果
name:caocao age:19
Person{name='caocao', age=19}
注意事项:
toString 方法会在 println 的时候被自动调用.
将对象转成字符串这样的操作我们称为 序列化.
toString 是 Object 类提供的方法, 自己创建的 Person 类默认继承自Object 类,
可以重写 toString 方法实现我们自己版本的转换字符串方法.
@Override称为 “注解”, 此处 @Override 表 toString 方法是重写了父类的方法.
toString快捷键:alt+f12(insert)
8.匿名对象
匿名只是表示没有名字的对象.
匿名对象称为没有引用的对象.
匿名对象只能在创建对象时使用.
如果一个对象只是用一次, 后面不需要用了, 可以考虑使用匿名对象.
new Person("caocao",19).show(); 通过匿名对象调用方法
Person person1=new Person();
代码示例:
class Person {
private String name;
private int age;
public Person(String name,int age) {
this.age = age;
this.name = name;
}
public void show() {
System.out.println("name:"+name+" " + "age:"+age);
}
}
public static void main(String[] args) {
new Person("caocao",19).show();//通过匿名对象调用方法
}
执行结果
name:caocao age:19
内容重点总结
类中定义的属性,大概分为几类:类属性,对象属性。
被static所修饰属性、方法,特点是不依赖于对象.
我们只需要通过类名就可以调用其属性或者方法。只有一份。
一个类可以产生无数的对象,类就是模板,对象就是具体的实例。
this关键字代表的是当前对象的引用。并不是当前对象。
静态代码块 优先 实例代码块 优先 构造函数执行。