二、面向对象
1.面向对象思想的落地法则
(1)设计类并设计类的成员(成员变量、成员方法)。
(2)通过类,来创建类的对象(实例化)。
(3)通过"对象.属性" 或 "对象.方法"来调用,完成相应的功能。
2.类的属性
(1)成员变量 VS 局部变量
相同点:
a、遵循变量声明的格式:数据类型 变量名 = 初始化值
b、都有作用域
不同点:
a、声明的位置不同。
成员变量:声明在类里,方法外。
局部变量:声明在方法内,方法的形参部分,代码块内。
b、成员变量的修饰符有四个:public private protected 缺省
局部变量 没有修饰符
c、成员变量有默认值,不必要显示的初始化赋值。
局部变量没有默认值,要进行初始化赋值。
d、在内存中存放的位置不同:
成员变量:存在于堆空间中,局部变量:栈空间中
3.类的方法(提供某种功能的实现)
(1)格式
权限修饰符 返回值类型 (void:无返回值/具体的返回值)方法名(形参){
程序代码
return 返回值;
}
(2)关于返回值类型:
void:表示此方法不需要返回值
有返回值的方法 return + 返回值类型对应的变量。
(3)方法中的一些概念
形式参数:在方法被调用时用于接收外部传入的数据的变量。
参数类型:就是该形式参数的数据类型。
返回值:方法在执行完毕后返还给调用它的程序的数据。
返回值类型:方法要返回的结果的数据类型。
实参:调用方法时实际传给函数形式参数的数据。
(4)方法的重载(overload)
a、在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可
b、重载示例:
//返回两个整数的和
int add(int x,int y){return x+y;}
//返回三个整数的和
int add(int x,int y,int z){return x+y+z;}
//返回两个小数的和
double add(double x,double y){return x+y;}
(5)方法的重写(override)
前提:有子类继承父类
子类继承父类后,若父类的方法对子类不适用,那么子类可以对父类的方法进行重写。
子类方法的"返回值类型 方法名 (参数列表)"于父类的方法一样
(4)可变个数的形参的方法(JDK1.5新特性)
a、可变参数:方法参数部分指定类型的参数个数是可变多个
b、声明方式:方法名(参数的类型名...参数名)
c、可变参数方法的使用与方法参数部分使用数组是一致的
d、方法的参数部分有可变形参,需要放在形参声明的最后
(放在第一个的化,如果这个可变参数,传递的个数是0个就会发生错误)
//示例代码:
写一个类,此类提供一个求多个数的和方法。
//一般用方法的重载
public int getSum(int x,int y){
return x + y;
}
public int getSum(int x,int y,int z){
return x + y + z;
}
//传递一个数组
public int getSum(int[] args){
int sum = 0;
for (int i = 0; i < args.length; i++) {
sum += args[i];
}
return sum;
}
//可变个数的形参 可以传递一个或多个参数
public int getSum(int ... args){
int sum = 0;
for (int i = 0; i < args.length; i++) {
sum += args[i];
}
return sum;
}
4.构造器(构造方法)
(1)构造器的特征
它具有与类相同的名称
它不声明返回值类型。(与声明为void不同)
不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
(2)构造器的作用
创建对象;给对象进行初始化
例如:Order o = new Order(); Person p = new Person(Peter,15)
(3)语法格式
修饰符 类名 (参数列表) {
初始化语句;
}
(4)根据参数不同,构造器可以分为如下两类
隐式无参构造器(系统默认提供)
显式定义一个或多个构造器(无参、有参)
(5)注意:
默认构造器的修饰符与所属类的修饰符一致
一旦显式定义了构造器,则系统不再提供默认构造器
一个类可以创建多个重载的构造器
父类的构造器不可被子类继承
5.权限修饰符
(1)Java权限修饰符public、protected、private置于类的成员定义前,用来限定对象对该类成员的访问权限。
(2)对于class的权限修饰只可以用public和default(缺省)
6.关键字 this、super
(1)this
a、可以用来修饰属性、方法、构造器
b、this理解为当前对象或当前正在创建的对象。
c、可以在构造器中通过“this(形参)” 的方式显式的调用本类中其他重载的指定的构造器。
d、当形参与成员变量重名时,如果在方法内部需要使用成员变量,必须添加this来表明该变量时类成员(否则参数传过来,赋给成员变量为初始值)
示例代码:
class Person{ // 定义Person类
private String name ;
private int age ;
public Person(){ // 无参构造
System.out.println("新对象实例化") ;
}
public Person(String name){
this(); // 调用本类中的无参构造方法
this.name = name ;
}
public Person(String name,int age){
this(name) ; // 调用有一个参数的构造方法
this.age = age;
}
public String getInfo(){
return "姓名:" + name + ",年龄:" + age ;
}
public static void main(String[] args) {
Person person = new Person("xue");
String s = person.getInfo();
System.out.println(s);
Person person1 = new Person("jiang",20);
String s1 = person1.getInfo();
System.out.println(s1);
//新对象实例化
//姓名:xue,年龄:0
//新对象实例化
//姓名:jiang,年龄:20
}
}
(2)super
a、可以用来修饰属性、方法、构造器
b、当子类与父类中有同名的属性时,可以通过"super.属性"显示的调用父类中声明的属性。若想调用子类同名的属性"this.属性"
c、当子类重写父类的方法之后,在子类中调用父类中被重写的方法,使用"super.方法"
d、super可用于在子类构造方法中调用父类的构造器
注意:
子类中所有的构造器默认都会访问父类中空参数的构造器。
当父类中没有空参数的构造器时,子类的构造器必须通过 this(参数列表)或者super(参数列表)语句指定调用本类或者父类中相应的构造器,且必须放在构造器的第一行。
在设计类时,最好提供一个空参的构造器,不然子类写空参构造器时会报错
示例代码:
//父类
public class Person {
private String name;
private int age;
int id = 1001;
public Person(){
this.name = "xue";
this.age = 20;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉哦");
}
}
//子类
public class Student extends Person {
private int id = 1002;
public Student() {
super(); //调用父类的构造器
}
public void eat() { //重写eat方法
System.out.println("学生吃饭");
}
public void show() {
String name = getName();
System.out.println(name);//xue
int age = getAge();
System.out.println(age);//20
System.out.println(super.id); //1001 调父类的属性 id
System.out.println(this.id); //1002 调本类的属性 id
super.eat(); //吃饭 调父类的方法 eat
this.eat(); //学生吃饭 调本类的方法 eat
sleep(); //前面使用super或者this都可以,因为这个方法没有重写
}
}
//测试类
public class TestStudent {
public static void main(String[] args) {
//Student类被实例化时,创建构造器,此构造器通过super调用父类构造器
Student student = new Student();
student.show();
}
}
7.面向对象的特性
(1)封装性
a、给类的属性,设置权限修饰符private,设置此修饰符后,该类实例化,不能直接访问属性 对象.属性
b、使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作。
(2)继承
a、通过 "class A extends B"类实现类的继承(子类 A 父类 B)
b、子类继承父类后,父类中声明的属性和方法,子类就可以获取的到
c、extends: 子类是对父类功能的扩展,子类可以有自己的属性、方法。
d、单继承: 一个类只能继承一个父类。
e、一个父类可以有多个子类
示例代码:
//定义一个父类
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void sleep(){
System.out.println("睡觉哦");
}
}
public class Man extends Person { // Man类继承Person类
public static void main(String[] args) {
Man man = new Man();
man.sleep(); //睡觉哦
}
//方法的重写
public void sleep(){
System.out.println("失眠了");
}
}
(3)多态性
多态性可以理解为一个事物的多种表现形态。
方法的重载和重写
示例代码:
//定义一个父类
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void shopping(){
System.out.println("购物");
}
}
//定义一个子类
public class Man extends Person {
private int id;
public Man() {
}
public Man(int id,String name,int age) {
super(name,age);
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void shopping(){
System.out.println("男人购物");
}
public void smoking(){
System.out.println("男人抽烟");
}
}
//测试类
public class TestPerson {
public static void main(String[] args) {
//子类对象的多态性:父类的引用指向子类对象
Person man = new Man(); //向上转型
//虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写的方法。
man.shopping(); //男人购物
//子类所特有的属性和方法不能调用
//man.smoking();
Man man1 = (Man)man;//向下转型 跟基本数据类型的转化有异曲同工之妙
man1.smoking(); //男人抽烟
}
}
(4)多态性的应用举例
示例代码:
public class TestAnimal {
public static void main(String[] args) {
TestAnimal test = new TestAnimal();
test.show(new Cat());
}
public void show(Animal a){
a.eat();
a.sleep();
if(a instanceof Dog){ //判断a是否是Dog对象的实例
Dog dog = (Dog)a;
dog.dogMethod();
}else if(a instanceof Cat){
Cat cat =(Cat)a;
cat.catMethod();
}
}
//如果不用多态性,将要创建多个方法
// public void show(Dog a){
// a.eat();
// a.sleep();
// }
//
// public void show(Cat a){
// a.eat();
// a.sleep();
// }
}
class Animal{
private String name;
private int age;
public void eat(){
System.out.println("进食");
}
public void sleep(){
System.out.println("睡觉");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void sleep(){
System.out.println("狗睡觉");
}
public void dogMethod(){
System.out.println("call 汪汪汪");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void sleep(){
System.out.println("猫睡觉");
}
public void catMethod(){
System.out.println("call 喵喵喵");
}
}