Java有三大特性:封装、继承、多态
1.封装
就是把类的某些信息隐藏在类内部,不允许外部程序直接访问,但是可以通过该类提供的方法来实现对隐藏信息的操作和访问。
好处:
1、良好的封装能够减少耦合
2、类内部的结构可以自由修改
3、可以对成员进行更精确的控制
4、隐藏类的实现细节,方便修改和实现
步骤:
1.修改属性的可见性 设为private
2.创建setter、getter方法用来读写属性值,可以控制哪些属性是可以给外部类读取的
3.在属性setter/getter方法中进行属性值合法性校验
public Class Animal{
private String type; //动物类别
privare int age; //动物年龄
private float weight; //动物体重
//体重是私密的 不提供getter()方法 -_-
public void eat(){
System.out.println("animal eat!");
}
public String getType(){
Return type;
}
public void setType(String type){
this.type = type;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public void setWeight(float weight){
this.weight = weight;
}
public Animal(String thisType){
type = thisType;
System.out.println("this is a "+type);
}
public String toString(){
reutrn "Animal[type=]"+type+",age="+age+"]";
}
}
工作项目上通常是把数据库的表结构封装成对象使用,所以使用过的对象类里的get和set方法没有在方法里进行值合法校验,此次学习才了解到,在数据库中表示性别、类别等属性通常用数值0 1 …等表示,这样的话为了方便在使用时直接输出对应的想要展示的内容,就可以在getter/setter方法中做转换,这样就不用在项目中每处调用该方法的地方都做转换。
如下:
public getType(){
switch(type){
case "0":
return "Dog";
break;
case "1":
return "Cat";
break;
default:
return "Human";
break;
}
}
封装对象类里常用到的还有重写一些方法,比如上面代码里的toString()方法,同理还有equals方法也很常用,在equals方法中设置需要对比的属性值。
2.继承
继承就是子类可以拥有父类的属性和行为。
特性:
- 子类拥有父类非private的属性、方法;
- 子类可以拥有自己的属性和方法,即可以对父类进行扩展,使子类A有别于子类B;
- 子类可以用自己的方式实现父类的方法;
- Java继承是单继承,但是可以多重继承
- 提高了类之间的耦合性(这是继承的缺点,耦合度高就会造成类之间的联系紧密度,代码独立性越差)
如上例中,animal作为父类,子类则可以是具体的类别如食草动物或者食肉动物(按不同侧重点分类),但是我不了解具体分类,所以在这里直接以Cat和Dog作为子类
public class Cat extends Animal{
public Cat(String type){
super(type);
}
public void eat(){
System.out.println("Cat eat!");
}
public void eatTest(){
this.eat(); //调用自己的eat()
super.eat(); //调用父类Animal的eat()
}
}
public class Dog extends Animai{
public Dog(String type){
super(type);
}
}
注意,Java不支持多继承,但是支持多重继承:
1).单继承:
public class A{…}
public class B extends A{…}
2).多重继承:
public class A {…}
public class B extends A{…}
public class C extends B{…}
3).不同类继承自同一个类:
public class A {…}
public class B extends A{…}
public class C extends A{…}
4).Java不支持的多继承!!(错误示例)
public class A{…}
public class B{…}
public class C extends A,B{…}
关键字
继承可以使用extends和implements这两个关键字来实现,所有的类都继承于java.lang.Object,当一个类没有这两个继承关键字时,默认这个类继承于Object祖先类(Object类在java.lang中,所以不需要import)java.lang包不需要导入(详情:别人的博客 侵删https://www.cnblogs.com/zedosu/p/6518124.html)
a.extends关键字用于类的继承,且为单一继承(extends只能继承一个类)
b.implements关键字用于接口的实现,实现一个接口必须实现接口中的所有方法;
支持多继承,可以实现多个类,多各类名用逗号分开(如上注意(4)格式)
c.super关键字:实现对父类成员的访问,用来引用当前对象的父类
this关键字:指向自己的引用
如上Cat类中的eatTest()方法,测试输出:
public class test(){
public static void main(String[] args){
Animal a = new Animal();
a.eat();
Cat c = new Cat();
c.eatTest();
}
}
输出结果:
animal eat!
Cat eat!
animal eat!
d.final关键字:final可以定义类/方法为不能继承/重写的
e.构造器:子类不继承父类的构造器,但是可以调用,调用方法如上例super(type);有入参的构造器调用时需要显式匹配入参列表;如果父类构造器没有参数,则不需要特意使用super调用,系统会先自动调用父类的无参构造器。
3.多态
多态就是同一行为(方法调用)具有不同表现形式的特性;
即同一个接口,被不同的实例对象调用会执行该对象对应的操作。
静态多态性:指的是程序在编译时,系统就能决定调用哪个函数,如重载。
动态多态性:指在运行中才能动态确定操作指针所指的对象,主要通过虚函数和重写来实现。
多态存在的三个必要条件:
-
继承
-
重写
-
父类引用指向子类对象(向上转型)
实现形式
Java中实现多态的形式:继承和接口
1.基于继承的多态实现方式---重写
以上文Animal和Cat的父子关系为例:
public class Animal{
// 其他属性和方法隐藏
public void func1(){
System.out.println("Animal func1 !");
eat();
}
public void eat(){
System.out.println("Animal eat!");
}
}
public class Cat extends Animal{
// 其他属性和方法隐藏
public void func1(String name){
System.out.println("Cat func1 name:"+name);
eat();
}
public void eat(){
System.out.println("Cat eat!");
}
}
public static void main(String[] args){
Animal cat = new Cat("Cat");
cat.func1();
}
输出:
this is a Cat
Animal func1!
Cat eat!
Animal cat = new Cat("Cat");这句代码表示用父类Animal创建子类对象Cat(Cat is-a Animal);也就是我经常混淆的一句经典的引用和对象关系定义:类型引用指向一个对象,即定义了一个Animal类型(父类类型)的引用,指向新建的Cat类型(子类类型)的对象。
基于继承的多态,子类对象将拥有父类的所有属性和方法(可以调用),但是不能调用或拥有子类的特有属性和方法,除非是子类重写了父类的方法(对于子类中定义而父类中没有的方法,它是无可奈何的);这样可以使用子类更强大的功能,又可以拥有父类的共性。
2.基于接口
继承是单继承,子类通过重写父类方法实现类的多态;而接口可以被多重实现,它能够利用一组相关或者不相关的接口进行组合与扩充,能够对外提供一致的服务接口。所以它相对于继承来说有更好的灵活性。