面向对象3
1封装
/*
封装:
具体表现: 属性/方法使用private权限
使用后外部无法直接访问,就要在它的类中提供相应的方法,
通过该方法实现外部对本类中私有属性/方法的操作/访问
*/
public class Person {
//私有属性,外部无法直接访问
private String name;
private int age;
//专门为外部提供的访问本类私有属性的方法
public void setName(String n){
if (n != null){
name = n;
}
}
public String getName(){
return name;
}
}
public class Test {
public static void main(String[] args) {
Person p1 = new Person();
p1.setName("张三");
System.out.println(p1.getName());
}
}
2继承
/**
* 继承
* 从已有类中派生出新类,新类可拥有父类的所有非私有的属性
* 是一种 is-a的关系
*
*/
public class Animal {
private String name;
private int age;
public Animal(){
System.out.println("animal的无参构造方法");
}
public Animal(String n,int a){
System.out.println("animal的有参构造方法");
name = n;
age = a;
/*System.out.println(name);
System.out.println(a);*/
}
public void eat(){
System.out.println("动物会吃!");
}
public void setName(String name){
this.name = name;
}
public String getName() {
return this.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();//默认调用父类无参构造方法,可不写,显示的写出来也要写在子类的第一行
super("来福",3);//调用父类有参构造方法,也在子类的第一行
System.out.println("dog的无参构造方法");
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void study(){
System.out.println("我是一只会学习的狗!");
}
}
public class Test {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();//调用的是子类中重写的父类吃方法
}
}
2.1类之间的关系
/*
类之间的关系 : 关联 依赖
1 关联:一个类作为另一个类的属性类型存在
是 has-a 的关性
分 一对一关联 一对多关联
2 依赖:B类作为另一个类的参数在方法中被使用
是 use-a 的关性
*/
public class Mobile {
private String name;
private double price;
public void tonghua(){
System.out.println("通话中......");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
/*
类之间的关系 : 关联 依赖
1 关联:一个类作为另一个类的属性类型存在
是 has-a 的关性
分 一对一关联 一对多关联
2 依赖:B类作为另一个类的参数在方法中被使用
是 use-a 的关性
*/
public class Person {
private String name;
private int age;
//关联关系
private Mobile mobile;//一对一
//private Mobile[] mobiles;//一对多
/**
* 依赖
* @param mobile
*/
public void call(Mobile mobile){
mobile.setName("jim");
mobile.tonghua();
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 Mobile getMobile() {
return mobile;
}
public void setMobile(Mobile mobile) {
this.mobile = mobile;
}
}
3多态
/**
* 多态:
* 1 有继承
* 2 有方法的重写
* 3 父类引用指向子类对象
*/
public abstract class Animal {
int num = 10;
private String name;
private int age;
//抽象方法,将在在子类中进行重写
public abstract void eat();
public static void sleep(){
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 Cat extends Animal {
private String name;
private int age;
@Override
public void eat() {
System.out.println("我是一只吃鱼的猫");
}
}
public class Dog extends Animal {
int num = 8;
private String type;
//方法重写
@Override//java中事先定义好的标签
public void eat() {
System.out.println("我是一只会吃骨头的狗!");
}
public static void sleep(){
System.out.println("狗睡觉");
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void study(){
System.out.println("我是一只会学习的狗!");
}
}
public class Test {
public static void main(String[] args) {
//父类Animal 引用指向 子类对象new Cat()/Dog()
Animal cat = new Cat();
Animal dog = new Dog();
//成员方法 : 编译看左边 运行看右边
dog.eat();//(编译时调用的是父类的吃方法,因为dog是Animal类型的,)(运行的是Dog类中重写的吃方法)
//静态方法 : 编译运行都看左边
dog.sleep();
//成员变量 : 编译运行都看左边
System.out.println(dog.num);//调用的是动物类中的成员变量
}
}
/*
方法参数多态性的好处:提高代码的扩展性
方法的形式参数类型是父类类型,而传递的实际参数可以是任意子类的对象
*/
public class Test2 {
public static void main(String[] args) {
//方法参数多态性的好处:提高代码的扩展性
//方法的形式参数类型是父类类型,而传递的实际参数可以是任意子类的对象
Dog dg = new Dog();
Test2 t2 = new Test2();
t2.feedAnimal(dg);
Cat ct = new Cat();
t2.feedAnimal(ct);
}
public void feedAnimal(Animal animal){
animal.eat();
}
/*
非多态的实现
*/
/*public static void main(String[] args){
Test t1 = new Test();
Dog dg = new Dog();
Cat ct = new Cat();
t1.feedDog(dg);
t1.feedCat(ct);
}
public void feedDog(Dog d){
d.eat();
}
public void feedCat(Cat c){
c.eat();
}*/
}
/*
多态带来的问题 : 父类类型不能访问子类特有方法
解决办法 : 向下转型
*/
public class Test3 {
public static void main(String[] args) {
Animal animal = new Dog();//属于向上转型
if (animal instanceof Dog){
Dog d = (Dog)animal;//向下转型
d.eat();//转型后可调子类特有方法
}else{
System.out.println("不是Dog类型");
}
}
}
4final关键字
/**
* final关键字:
* 1 修饰的方法不能被继承
* 2 修饰的属性要赋值 直接赋值(所有对象都一样,每次创建对象都会赋值一份 ; 加上static后所有对象共享且值一样)
* 在构造方法中赋值(当每个对象都想有自己的值时使用)
* 3 修饰的方法不能被重写
*/
public class Father {
int k = 9;
public final static int NUM = 10;
// final int num;
public Father() {
}
/*public Father(int num){//在构造方法中赋值(当每个对象(f1 f2)都想有自己的值时使用)
this.num = num;
}*/
public final void speak(){
System.out.println("啊啊啊啊啊啊");
}
public void makemoney(final int k){
//k = 9;
}
public static void main(String[] args) {
/*Father f1 = new Father(12);
System.out.println(f1.num);
Father f2 = new Father(13);
System.out.println(f2.num);*/
}
}
//public class Son extends Father { final修饰了Father类,所以Father类不能被son继承
public class Son extends Father {
/*final修饰的方法不能被重写
public final void speak(){
System.out.println("啊啊啊啊啊啊");
}*/
}
5抽象类
抽象类:即类中有未实现功能的方法
1 不能实例化对象,类的成员变量 成员方法 构造方法和普通类的访问方式一样
2 含有抽象方法的类一定是抽象类,抽象类可以有普通方法
3 一般作为基类
4 一个类如果要继承一个抽象类: 1 重写抽象类中所有方法
2 将当前类也声明为抽象类
5 静态方法 构造方法不能用abstract修饰抽象方法: 1 只有声明,没有实现
2 必须用abstract修饰
3 无方法体
public abstract class Animal {
//成员变量
int num;
//构造方法
public Animal(){
}
//抽象方法
public abstract void eat();
//普通方法
public void sleep(){
}
public static void main(String[] args){
//Animal a = new Animal();不能实例化对象
}
}
// 一个类如果要继承一个抽象类: 1 重写抽象类中所有方法 || 2 将当前类也声明为抽象类
// public abstract class Cat extends Animal {1 将当前类也声明为抽象类
public class Cat extends Animal {
//2 重写抽象类中所有方法
@Override
public void eat() {
}
}
6接口
接口 : 1 是一种特殊的抽象类
2 使用interface关键字
3 接口中成员变量默认为是静态常量
4 可定义 抽象方法 默认方法 静态方法
5 实现接口( implements): 将当前类声明为抽象类 或 重写接口中的抽象方法
6 接口中默认方法通过子类对象调用 7 接口中的静态方法通过接口名访问
public interface Animal {
int num = 8;
//接口中成员变量默认为是静态常量
public static final double PI = 3.14;
//抽象方法
void eat();
//默认方法
default void sleep(){
System.out.println("接口中的默认方法");
}
//静态方法
static void drink(){
System.out.println("接口中的静态方法");
}
}
//实现接口 使用implements关键字 1 将当前类声明为抽象类 2 重写接口中的抽象方法
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("狗吃");
}
}
public class Test {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();//狗类中重写的方法
d.sleep();//接口中的默认方法通过对象调用
Animal.drink();//接口中的静态方法通过接口名调用
//多态实现
Animal a = new Dog();
a.eat();
a.sleep();
}
}