Java–05
第三章 面向对象
目录
前言
21世纪,走进了信息时代,各种各样的软件层出不穷,但是总离不开程序开发,离不开程序开发语言,Java语言作为人们所熟知的一门语言,对于其有必要进行系统的学习。
一、包
在物理上是文件夹,用于管理类;
其作用有:
1.避免类重名
2.按功能管理类
3.控制访问权限
全类名=包名(包的地址)+类名
import关键字:用于导入外部的包;
当导入不同包中的同一个类时,第二个类名需要使用全类名。
import java.util.Date;
public class Demo1 {
public static void main(String[] args) {
Date date = new Date();
//当导入不同包下的同名类时,需要使用全类名
java.sql.Date date1 = new java.sql.Date(10l);
}
}
包的命名规范:
第一级:该项目的类型,如com,edu,gov,org等;
第二级:指所开发或运行的公司名称,如oracle,sun等;
第三级:指项目的名称,如erp,cms等;
第四级:指项目的模块名称,如action等,
根据具体需要,还可增加第五级,第六级
。
包名要求全小写。
二、访问权限修饰符
分为四种public,protected,(default),private。
public即公共权限,可以修饰类,属性,方法,可以被任意访问。
protected即受保护的权限可以修饰属性,方法,同包类可以访问,或者是不同包的子类访问。
(default),其并不出现在修饰符位置,当不写时,默认就为default权限,可以修饰类,属性,方法,同包即可访问。
private即私有权限,可以修饰属性与方法,仅仅只可以被当前类访问。
public class Demo2 {
public int pnum;//公共权限 public可以修饰类,属性,方法,可以被任意访问
protected int pronum;//受保护的权限 protected 可以修饰属性,方法,可以被不同包的子类访问,同包也可以访问
int num;//默认的权限 (default)可以修饰类,属性,方法,可以被同包访问
private int prvnum;//私有权限 private 可以修饰属性,方法,可以被当前类访问
public void test() {
System.out.println(pnum);
System.out.println(pronum);
System.out.println(num);
System.out.println(prvnum);
}
}
public class Demo3 {
//同包下可访问public,protected,(default)
Demo2 demo2 = new Demo2();
public void test() {
System.out.println(demo2.pnum);
System.out.println(demo2.pronum);
System.out.println(demo2.num);
}
}
这是另一个包中,调用Demo2
import com.company.project.test.day8.Demo2;
//跨包下,可访问public,通过继承,可以访问父类的protected成员
public class Demo1 extends Demo2 {
Demo2 demo2 = new Demo2();
Demo1 demo1 = new Demo1();
public void test1() {
System.out.println(demo2.pnum);
System.out.println(demo1.pronum);//继承父类后,子类可以调用父类的protected修饰的属性和方法
}
}
三、面向对象的三大特征–封装
封装即将类中的一些属性,方法隐藏在类的内部,而不向外展示,如今的软件为了使大多数人易于使用,往往将操作简易化,用于只需要进行简单地操作,即可达到想要的结果,而不需要了解内部的运行;封装后的代码不允许外部的程序直接访问,也增强了安全性,但是为了程序内部的一些使用,需要使用一些方法去访问和使用这些封装过的内容;
简易的封装,如属性封装:
private String name;
private int age;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
封装后的属性无法被其它类直接访问,但是可以通过方法,进行访问:
public static void main(String[] args) {
Demo1 d = new Demo1();
d.setName("张三");
d.setAge(18);
System.out.println(d.getName() + ":" + d.getAge() + "岁");
}
封装的好处:隐藏类的细节;只能通过规定的方法访问;方便加入控制语句;方便修改实现;
this关键字:在封装的方法中常会使用到this关键字,用来代指当前调用方法的对象,但是必须被放在非静态方法中,可以用this引用成员变量或者成员方法;
四、面向对象的三大特征–继承
1.继承概念
指,从旧的类中,派生出新的类,新的类可以吸收旧的类中的属性和方法,并能扩展出新的能力;旧的,被派生的类叫做父类或者基类,新的类叫做派生类或者子类;
一般继承关系为“is-a”关系,如猫是动物,猫为子类,动物为父类;
继承使得代码可重用,提高了代码的可扩展性;
Java中的继承:
①使用extends关键字表示继承;
②不支持多继承,一个类只能有一个直接父类;
③子类可以调用父类非私有的成员;
继承的结构为:
[访问权限修饰符][修饰符] class 子类名 extends 父类名{
类体;
}
一个类只能有一个直接父类,但允许,被继承的类作为父类,即C继承于B,B继承于A;
当类没有继承任何类时,jvm会默认为该类继承object,object是为所有类准备的父类;
2.继承中的构造方法
在子类继承父类后,创建对象时会先创建父类对象,所以在子类对象创建后可以使用父类的非私有成员;
子类的构造方法实际上先调用了父类的默认无参的构造方法,在子类构造方法的第一行可以使用super关键字调用父类的构造方法(有参或者无参);
super关键字,在继承中代表父类引用,在构造方法中必须写在第一行,可以通过super.属性名(方法名)调用父类的非私有成员;
public class Animal {
private String name;
private int age;
public Animal(){
System.out.println("Animal无参构造方法");
}
public Animal(String name,int age){
this.name=name;
this.age=age;
System.out.println("Animal有参构造方法");
}
public void eat() {
System.out.println(name+"在吃");
}
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 class Dog extends Animal {
private String type;
public Dog() {
super();
System.out.println("Dog无参构造方法");
}
public Dog(String name, int age, String type) {
super(name, age);
this.type = type;
System.out.println("Dog有参构造方法");
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
3.方法重写
Override,在子类中,可以根据需要对父类继承来的方法进行重写;重写要求子类的方法与父类结构完全相同(访问权限修饰符,返回值类型,方法名,参数列表);
public class Animal {
private String name;
private int age;
public Animal() {
//System.out.println("Animal无参构造方法");
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
// System.out.println("Animal有参构造方法");
}
public void eat() {
System.out.println(name + "在吃");
}
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;
}
}
重写了父类的eat方法;
public class Dog extends Animal {
private String type;
public Dog() {
super();
// System.out.println("Dog无参构造方法");
}
public Dog(String name, int age, String type) {
super(name, age);
this.type = type;
// System.out.println("Dog有参构造方法");
}
/*
* 在子类中可以根据需要,对父类的方法进行重写。静态方法不可以重写
* 子类重写的方法结构需要和父类完全相同(访问权限,返回值类型,方法名,参数列表)
*/
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
类与类的关系
1.关联
即“has-a”关系,对象与对象之间的连接。一个类作为另一个类的属性;按照关联方向分为:单向关联与双向关联;
按照结构分一对一关联,一对多关联;
2.依赖
即“use-a”关系,指一个类作为另一个类的局部变量;具有偶然性,临时性;作为变量的类变化,会影响到调用的类;
public class Computer {
private String name;
private int price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
public class Person {
private String name;
private int age;
private Computer computer;//关联关系:一个类作为另一个类的属性 has-a关系
public void call(Phone phone) {//依赖关系:一个类使用到另一个类,作为局部变量 use-a关系
System.out.println(name + "使用" + phone.getName() + "手机打电话");
}
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 Computer getComputer() {
return computer;
}
public void setComputer(Computer computer) {
this.computer = computer;
}
}
五、面向对象的三大特征–多态
多态是指一个事物,在不同时刻的多种表现;
多态有三个前提:
①继承;
②重写方法;
③父类引用指向子类对象(编译期类型时父类,运行期类型是子类);
静态成员,成员变量:编译与运行都看左边;
成员方法:编译看左边,运行看右边
如:
public class Animal {
private String name;
private int age;
public Animal() {
//System.out.println("Animal无参构造方法");
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
// System.out.println("Animal有参构造方法");
}
public void eat() {
System.out.println(name + "在吃");
}
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 class Cat extends Animal {
private String name;
private int age;
@Override
public void eat() {
System.out.println("猫咪吃鱼");
}
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 class Dog extends Animal {
private String type;
public Dog() {
super();
// System.out.println("Dog无参构造方法");
}
public Dog(String name, int age, String type) {
super(name, age);
this.type = type;
// System.out.println("Dog有参构造方法");
}
/*
* 在子类中可以根据需要,对父类的方法进行重写。静态方法不可以重写
* 子类重写的方法结构需要和父类完全相同(访问权限,返回值类型,方法名,参数列表)
*/
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public void run(){
System.out.println("狗狗会跑");
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public class Test {
public static void main(String[] args) {
/*
成员方法:左边编译期,右边运行期,编译时调用的为父类中的方法,运行时根据对象不同,调用重写后的方法
静态方法,成员属性:编译和运行都看左边;
*/
Animal dog = new Dog();//向上转型,但是父类无法调用子类特有的方法
Animal cat = new Cat();
Test test = new Test();
Dog dog1=(Dog)dog;//向下转型,类似于强制类型转换
dog1.run();
test.feed(dog);
test.feed(cat);
}
public void feed(Animal animal) {
animal.eat();
}
}
笔记如有错误,遗漏之处,欢迎指正!