一.面向过程和面向对象:
面向过程:以过程为中心的编程思想,实现功能的每一步都是自己实现。
面向对象:以对象为中心的编程思想,通过指挥对象实现具体的功能。
例如“洗衣服‘’的实现,面向过程就是需要自己一步步实现每一个洗衣步骤,但面向对象就像是调用“洗衣店”这个对象,你只需要把衣服送到洗衣店,由洗衣店帮你实现洗衣功能。
二.类和对象
类:所有具有相同属性、行为的事物的抽象集合,例如人类、教师、医生等,类包括属性(事物的特征)和行为(事物执行的操作)。
对象:每一个客观存在的事物都能看做对象,比如“刘老师”“李医生”等具体的实体。
属性:在类中通过成员变量来体现(类中方法外的变量)
行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)
(1)类的定义步骤:
① 定义类
② 编写类的成员变量
③ 编写类的成员方法
例如定义一个学生类:
public class StudentClass { String name; char gender; int age; public void Stud(){ System.out.println("喜欢学习!"); } }
此处name、gender等就是成员变量,也是学生类的属性,而Stud是成员方法,同时是类的行为。
(2)对象的创建和调用:
-
创建对象的格式:
-
类名 对象名 = new 类名();
-
-
调用成员的格式:
-
对象名.成员变量
-
对象名.成员方法();
-
比如通过创建一个学生对象调用学生类里的变量和方法:
public class RunStu { //创建一个运行类 public static void main(String[] args) { //程序入口main函数 StudentClass Stu= new StudentClass(); //创建一个Stu的学生类 Stu.name="李华"; //“对象名.成员变量”可以给StudentClass类的变量name赋值 Stu.age=21; Stu.gender='男'; System.out.println(Stu.name); //打印name检查是否被赋值 System.out.println(Stu.age); System.out.println(Stu.gender); Stu.Stud(); //对象名.成员方法(); 可以调用成员方法Stud } }//运行结果为:
李华
21
男
喜欢学习!
三.成员变量和局部变量
成员变量:Java程序中在类中、方法外定义的变量。存放于堆内存中,随对象的存在而存在,随对象的消失而消失;有默认值,无需手动初始化。
局部变量:在方法内部或方法声明上定义的变量。存放于栈内存里,方法调用时出现,方法运行结束也会随之消失;无默认值,使用前需初始化。
四.封装
封装是面向对象的三大特征之一(封装,继承,多态), 是面向对象编程语言对客观世界的模拟,将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
通过方法来控制成员变量的操作,把代码用方法进行封装,提高了代码的复用性和安全性。
通常我们用private关键字来修饰类的成员变量,然后再在方法里用get、set来访问成员变量。
private关键字:private是一个修饰符,可以用来修饰成员(成员变量,成员方法),被private修饰的成员,只能在本类进行访问,针对private修饰的成员变量,如果需要被其他类使用,只能通过以下两个方法调用:
(1)提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰。
(2)提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰。
例如“洗衣服”的标准类(同时具有无参、有参构造方法、get、set、show方法的类)定义:
public class StanClass { private String cloth; //定义衣服的种类 private int clothNum; //定义衣服数量 private String washMethod;//定义衣服的洗涤方式 public StanClass() { //定义一个空参构造方法用于之后创建对象为成员变量赋值 } public StanClass(String cloth, int clothNum, String washMethod) { //定义一个带参构造方法用于之后创建对象为成员变量赋值 this.cloth = cloth; //“this”关键字是访问当前类的成员变量,该句是将括号内的参数值赋给成员变量 this.clothNum = clothNum; this.washMethod = washMethod; } public String getCloth() { //通过get方法获取成员变量的值,一定要用public修饰才能在所有类中调用该方法 return cloth; } public void setCloth(String cloth) { //通过set将括号内的值赋给成员变量,和带参构造方法作用一样 this.cloth = cloth; } public int getClothNum() { return clothNum; } public void setClothNum(int clothNum) { if (clothNum < 0) { //判断衣服数是否大于0 System.out.println("该衣服数不合法,请重新设置"); } else { this.clothNum = clothNum;//如果>0则将数值赋给成员变量clothNum System.out.println("衣服数为:"+clothNum); } } public String getWashMethod() { return washMethod; } public void setWashMethod(String washMethod) { this.washMethod = washMethod; } public void show() { System.out.println("衣服类型:" + cloth + ",衣服数量" + clothNum + ",洗衣方式:" + washMethod); } }测试该洗衣服类:
public class RunStan {//新建一个测试程序的类 public static void main(String[] args) { //主方法,是程序的入口 StanClass sc= new StanClass();//新建一个SC对象,用于调用StanClass类中的方法和成员变量,其实是调用了StanClass类的空参构造方法 sc.setCloth("羊绒大衣");//通过setCloth来设置cloth的值 sc.setClothNum(4); sc.setWashMethod("干洗"); System.out.println("修改前:"); sc.show(); System.out.println(sc.getCloth()); //通过getCloth来获取cloth的值再通过println将其打印出来 System.out.println("修改后:"); sc.setCloth("纱裙"); sc.show(); } }
由于被private(私有)关键字修饰的成员(成员变量,成员方法)只能被本类的方法调用访问,所以我们在类中定义一些public修饰的公共方法,在方法里调用这些成员变量和成员方法时,能正常使用,也可以在其他类调用这些公共方法来访问被private修饰的成员。
五.构造方法
构造方法用于给对象的数据(属性)进行初始化。
比如上述的Stu、sc对象,就是通过调用构造方法来进行赋值初始化
StudentClass Stu= new StudentClass();
StanClass sc= new StanClass(); //新建一个SC对象,用于调用StanClass类中的方法和成员变量,其实是调用了StanClass类的空参构造方法
构造方法有如下特性:
-
方法名与类名相同,大小写也要一致
-
没有返回值类型,连void都没有
-
没有具体的返回值(不能由retrun带回结果数据)
需注意:*
构造方法在创建对象的时候调用,每创建一次对象,就会执行一次构造方法;
不能手动调用构造方法;
如果没有定义构造方法,系统将给出一个默认的无参数构造方法 ;
如果定义了构造方法,系统将不再提供默认的构造方法;
无论是否使用,都手动书写无参数构造方法,和带参数构造方法。
比如在洗衣类里我们就构造了一个无参构造方法和一个带参构造方法:
public StanClass() { //定义一个空参构造方法用于之后创建对象为成员变量赋值
}
public StanClass(String cloth, int clothNum, String washMethod) { //定义一个带参构造方法用于之后创建对象为成员变量赋值
this.cloth = cloth; //“this”关键字是访问当前类的成员变量,该句是将括号内的参数值赋给成员变量
this.clothNum = clothNum;
this.washMethod = washMethod;
}
六.继承
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法。
继承通过extends实现。
继承可以让类与类之间产生关系,子父类关系,产生子父类后,子类则可以使用父类中非私有的成员。
格式为:class 子类 extends 父类 { }
例如:class Cat extends Animal{}
//以下代码定义了一个父类Animal和两个子类Cat、Dog public abstract class Animal { //父类Animal public abstract void eat(); //abstract关键字修饰方法时代表该方法是个抽象类,没有方法体 public void drink(){ System.out.println("喝水"); } }public class Cat extends Animal{ //子类Cat public void eat(){ System.out.println("猫吃鱼"); //cat继承了animal的eat方法,它重新定义了该方法在cat里的行为,父类中的drink方法没有在子类声明,后续测试也能获取 } }public class Dog extends Animal { //子类Dog @Override //是代表类和类之间有关系的标识,系统会自动生成,手动输入可用于检测两个类之间是否有继承关系 public void eat() { System.out.println("狗吃肉"); } }//测试代码如下:
public class TestAnimal { public static void main(String[] args) { Cat cat = new Cat(); //创建了cat对象 cat.eat();//通过cat对象调用了eat方法 cat.drink(); //通过cat对象调用了drink方法 Dog dog = new Dog(); dog.eat(); dog.drink(); } }//测试结果如下:
猫吃鱼
喝水
狗吃肉
喝水
继承提高了代码的复用性(多个类相同的成员可以放到同一个类中)和维护性,当代码有问题时,只需要修改一处就行。
但同时,继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性。
我们在使用继承时,需考虑类与类之间是否有包含关系,比如Animal和Cat有包含关系,所以可以将Animal定义为Cat的父类,让Cat继承Animal的公共属性和行为。
注意:
Java中类只支持单继承,不支持多继承,错误范例:class A extends B, C { };就像你只能拥有一个亲生父亲。
Java中类支持多层继承,就像你可以拥有爷爷,曾祖父。