学习面向对象三条主线
1. 类及类成员
属性(filed)
方法(method)
构造类(constructor)
语句块(block)
内部类(Inner)
2.三大特征
封装(encaosulation)
继承(inneritance)
多态(polymorphism)
3. 其他关键字
this, package, import, super, extends, implements, abstract, interface
instanceof, native, synchronized, volatile, final, static
面向对象与面向过程
面向过程:强调的是功能行为(实施者)
面向对象:强调具备了功能的对象(指挥者) 方法体现功能性
类和对象
类:是对现实世界事物的描述,是抽象的 (学生)
对象:是实际存在的该类事物的一个个体,因而也称实例 (小明)
可以理解为:类 = 汽车设计图;对象 = 实实在在的汽车
java类及类的成员
定义类其实是定义类中的成员(成员变量和成员方法)
属性:对应类中的成员变量(描述事物的特征) (身高、体重)
成员变量和对象同周期,同生共死
属性的隐式初始化值是0, JVM帮助我们做的
属性也可以有显式初始化值.
方法:对应类中的成员方法(描述事物的行为) (吃喝)
成员都可以使用访问控制修饰符来修饰, public , private
private 修饰成员, 表示是私有的. 只能在本类中使用, 可以被其他成员访问
封装 : 成员私有化, 其他类只能通过方法间接访问属性, 就可以在方法中进一步对属性有一个保护.
this表示对象, 通过this可以指明是它的属性和方法
创建类及对象示例
import java.util.jar.JarOutputStream;
//这是一个Dog类 类是对事物的抽象的描述 类也是一种类型 它是复合数据类型 其中可以包含多种数据类型
public class Dog {
String name;//这是类的属性
int age;
String type;
public void shout(){//这是类的方法 方法是具体行为、动作 负责功能的实现
System.out.println(name+":汪汪汪~");
}
public void eat(String some){
System.out.println(name+"在吃"+some);//成员互访 属性可以访问方法 方法可访问属性
}
public String say(){
String s = "姓名:" + name +",年龄:"+age+",品种:"+ type;
return s;
}
}
//这是一个测试类
public class DogTest {
public static void main(String[] args){
//局部变量在栈区 成员变量在堆区
//使用类模板创建对象 d是对象名 Dog是类类型 可以创建多个对象 每个对象都拥有自己的一套属性
Dog d = new Dog();//d不是对象 它是Dog类型的引用变量 保存一个Dog对象的地址 Dog对象在堆内存中
//给对象属性赋值
d.name = "黑子";
d.age = 5;
d.type = "中华田园犬";
//调用对象方法
d.shout();
d.eat("骨头");
String str = d.say();
System.out.println(str);
Dog d1 = new Dog();
d1.name = "小白";
d1.age = 4 ;
d1.type = "金毛";
System.out.println("------------------------");
d1.shout();
d1.eat("肉肉");
String str1 = d1.say();
System.out.println(str1);
// d1 = d ; //d1中的老地址就被刷新掉了,原来指向的对象就不再引用指向它,那个对象就变成垃圾对象,会被GC
// d1.age = 30;//虽然30刷给了d1 但此时 d和d1都指向了同一个地址空间 所以d和d1输出都相同
//交换变量引用不是对象交换 不会波及到对象 实际上是地址值的交换 (交换钥匙)
Dog tmp = d;//tmp只是个小引用
d = d1;
d1 = tmp;
System.out.println("------------------------");
System.out.println(d.say());
System.out.println(d1.say());
}
}
成员变量(属性)和局部变量的区别?
成员变量:
成员变量定义在类中,在整个类中都可以被访问。
成员变量分为类成员变量和实例成员变量,实例变量存在于对象所在的堆内存中。
成员变量有默认初始化值。
成员变量的权限修饰符可以根据需要,选择任意一个
局部变量:
局部变量只定义在局部范围内,如:方法内,代码块内等。
局部变量存在于栈内存中。
作用的范围结束,变量空间会自动释放。
局部变量没有默认初始化值,每次必须显式初始化。
局部变量声明时不指定权限修饰符
构造器(constructor)
也称为构造方法 : 作用是对象创建时进行初始化工作
特点 :
1) 方法名和类名一致, 所以它是唯一允许首字母大写的方法.
2) 没有返回值声明, 甚至连void也没有
3) 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
4) 不能像普通方法一样随意调用, 只能调用一次, 同一个对象的生命周期内只能调用一次.
如果在类中没有写构造器呢?
如果在类中没有写构造器, 编译器会自动添加一个缺省构造器.
缺省构造器 :
1) 修饰符和类一致.
2) 无参.
3) 无语句.
如果在类中写了构造器, 编译器就不再添加缺省构造器.
构造器重载
同一个类中, 构造器的参数不同, 可以形成重载.
构造器重载的好处是调用者可以随意使用构造器来创建对象.
构造器方法的名称在编译时会转换为<init>
会在创建对象时最后执行..
this(...) 必须放在第一行, 效果是连环调用先于本构造器的执行. 父类构造器先于子类构造器.
this(...) 一定要有一个构造器中是没有this(...)的. 否则会形成无限递归
构造器示例代码
public class MyDate {
/*
属性封装:成员私有化,使用private,使其他类只能通过方法间接访问属性,从而保护对象属性的数据
private:修饰成员,私有的,只能在本类中使用,可以被其他成员访问
在其他类中不能直接访问,可以使用set/get方法间接访问
*/
//private int year = 1998;//显式值
private int year;
private int month ;
private int day ;
//构造器1:无参无返回值
public MyDate(){
/*
this.year = 1998 ;
this.month = 2;
this.day = 8;
*/
/*
this(...)必须放在第一行,效果是连环调用先于本构造器的执行,父构造器优先于子构造器
this(...)一定要有一个构造器中是没有this(...)的,否则会形成无限递归
*/
this(1998,2,8);
System.out.println("MyDate()------------------");
}
//构造器2:有两个参数
public MyDate(int year, int month){
/*
this.year = year;
this.month = month;
this.day = 8;
*/
this(year,month,8);
System.out.println("MyDate(int year,int month)------------------");
}
//构造器3:有三个参数
public MyDate(int year, int month, int day){
this.year = year;
this.setMonth(month);
this.setDay(day);//要想非法数据能被判断出来,必须的去调用set方法
System.out.println("MyDate(int year,int month,int day)------------------");
}
public String say(){
String s = year+"年"+month+"月"+day+"日";
return s;
}
//set方法用于间接给属性赋值,无参有返回值
//方法的参数名最好详细且有意义,当参数和属性名冲突时,要特别加this限定,用于标识对象属性
public void setYear(int year){
//year = year; 左面的year会因为就近原则,定位的是参数name,而不是属性name
this.year = year;//this表示对象,this.name表示对象的name属性, 右面的year表示的是形参
}
//get方法用于间接获取属性值,无参有返回值
public int getYear(){
return this.year;
}
public void setMonth(int month){
if (month < 1 || month > 12 ){
return;
}
this.month = month;
}
public int getMonth() {
return this.month;
}
public void setDay(int day ) {
if (day < 1 || day > 31){//对参数进行合法性检查,使得非法数据无法给属性赋值,从而保护数据
return;
}
this.day = day;
}
public int getDay() {
return this.day;
}
}
public class MyDateTest {
public static void main(String[] args) {
//无参数
MyDate m3 = new MyDate();
System.out.println(m3.say());
//两个参数
MyDate m4 = new MyDate(2022,13);
System.out.println(m4.say());
//三个参数
MyDate m5 = new MyDate(2021, 90, 55);
System.out.println(m5.say());
}
public static void main1(String[] args) {
MyDate m1= new MyDate();
System.out.println("我的生日:"+m1.say());//输出对象的显式值
System.out.println("---------------------------------");
/*
MyDate m2= new MyDate();
m2.year = 2021;
m2.month = 8 ;
m2.day = 28;
System.out.println("今天的日期:"+m2.say());
*/
MyDate m2= new MyDate();
m2.setYear(2021);
m2.setMonth(8);//数据不合法,输出显式值
m2.setDay(287);
System.out.println("今天的日期:"+m2.say());
}
}
总结
今天主要学习的内容
1、Java类以及Java类中三个重要的成员:属性、方法、构造器
2、封装、private修饰符 、set/get方法
3、this的两大用处