Java基础学习(三) -- OOP的三大特征、向上和向下转型、内部类之详解

面向对象编程(OOP)的三大特征

什么是封装?
(1) 把对象的状态和行为看成一个统一的整体,将二者存放在一个独立的类中;
(2) "信息隐藏", 把不需要让外界知道的信息隐藏起来,向外提供统一的方法用于设置和读取属性,保证外界安全访问功能;  把所有的字段使用private私有化,不准外界访问,把方法使用public修饰,允许外界访问.
 
【注意】除了属性的封装,将需要重复使用的代码提取到方法中,这叫方法的封装。将相同的是属性和方法提取到一个类中也称为封住。
 
实现访问控制,限制属性访问。但不是拒绝访问。
 
作用:只能通过规定的方法进行访问数据,方便在方法中加入控制语句,防止不合法的数据赋值。
 
访问权限控制:
不写(缺省):  表示包私有,表示包访问权限.  访问者的包必须和当前定义类的包相同才能访问.
private:         表示私有的, 表示类访问权限.  只能在本类中访问,离开本类之后,就不能直接访问.
protected:    表示子类访问权限,同包中的可以访问,即使不同包,但是有继承关系,子类也可以访问父类的属性.
public:          表示全局的,可以公共访问权限,如某个字段/方法,使用了public修饰,则可以在当前项目中任何地方访问.
Java基础学习(三) -- OOP的三大特征、向上和向下转型、内部类之详解
方法重载: 在同一个类中,方法名相同,参数列表不同,与返回值和访问修饰符无关的多个方法构成方法重载。
参数列表不同: 参数的个数,参数类型,多个参数的前后顺序不同
方法重载的典型应用: 构造函数重载.

什么是继承?
  子类是对父类的拓展,是一种特殊的父类。不能继承父类的私有属性。
语法格式: 子类继承父类使用extends关键字   
public  class  子类类名    extends    父类类名
{
         编写子类中自己特有的状态和行为
}
 
子类中需要访问父类成员,使用super关键字。
super.属性 访问父类属性
super.方法() 访问父类方法
 
如果子类中没有同名的属性和方法覆盖掉父类的时候,依然可以使用this关键字进行访问父类的属性和方法。但是,如果子类中重写了父类的属性和方法,那么使用this关键字访问的是本类属性,super关键字访问父类的属性。
 
在子类的构造函数中使用super(),表示调用父类的构造函数,而且super()必须在子类构造的首行。
 
注意:即使使用super关键字,也不能访问父类中的私有属性。
 
继承后的初始化顺序:
父类属性-->父类构造-->子类属性-->子类构造
 
在Java中,继承只能单继承,不能多继承。但是可以多层继承。(父类-->子类-->子类的子类:子类的子类就具有父类和子类的属性和方法。)
 
方法重写:1.在子类中,重写父类方法。要求: 方法名相同,参数列表相同,返回值相同,访问控制符不能比父类更严格。
privated的属性和方法不能被继承,不能被重写。
 
overload和override的区别:
overload是方法重写:发生在子类中,方法名相同,返回值相同,参数列表相同,访问修饰符不能比父类更严格。
override是方法重载:放生在同一个类中,方法名相同,与返回值和访问修饰符无关,参数列表不同。
 
抽象类:使用abstract关键字修饰的类,称为抽象类。抽象类不能被实例化。
 
抽象方法: 使用abstract关键字修饰,而且没有方法体的方法称为抽象方法。子类继承抽象类,那么子类必须重写父类所有的抽象方法。除非子类也是抽象类,那样可以不需要重写父类的抽象类。抽象方法必须在抽象类中。抽象类中的方法不一定必须是抽象方法。
 
final:
(1)final修饰的类,是最终类,final修饰的类不能被继承。
(2)final修饰的方法,是最终方法,子类不能重写final方法。
(3)final修饰的变量,是常量,不可修改。常量的所有字母大写!
 
static:
(1)static可以用于修饰方法,属性,代码块。
(2)static修饰的方法和属性,称为类属性和类方法(静态属性和静态方法)。
(3)静态属性和静态方法,调用时直接使用类名直接调用,也可以使用实例化后的对象名调用。
注意:
1、成员属性和成员方法,也叫实例属性和实例方法,只能使用实例化后的对象名使用。
2、类属性和类方法是属于类的,在类装载的时候直接声明,而成员属性和成员方法是属于对象的,在对象的实例化时才可以产生。
3、静态属性和方法将先于非静态属性和方法产生。
4、非静态方法可以调用静态属性,静态方法中不能调用非静态属性。(静态方法先于对象产生,因此没有成员属性和方法)
5、由于类属性和类方法是属于类的,因此只会在类装载的时候产生一份。也就是说一个类的静态属性只能在类装载的时候产生一份,后续使用该类实例化的多个对象将共用同一个静态变量。
静态方法中不能使用this和super(this代表本类对象,super代表父类对象,所以产生静态方法时,还没有对象)。

多态:是同一种事物,由于条件的不同,执行多种操作,展示出不同的结果。(同一个引用类型,由于实例的对象不同,操作各不相同)
 
(1)优点:消除类型之间的耦合性、可替换性、可扩充性、接口性、灵活性、简化性。
(2)三个必要条件: 子类继承父类 、子类重写父类方法、父类引用指向子类的对象。
(3)当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
 

补充: instanceof:java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个例。写法:结果 = A instanceof B  (A是对象,B是类,B是A的父类或者是object类,将会返回tr


类的写法:
(1)一个.java文件中,可以有多个外部类。而且必须有一个与文件同名,与文件同名的这个类,一般使用public修饰.其他不与文件同名的类,必须不能用public修饰。
(2)所有的外部类,都不能使用protected和private修饰!必须使用public修饰或者省略不写!
(3)一个文件中,公开的类至多一个,而且,公开的类必须与文件同名。
(4)如果一个.java文件中有多个class,那么有几个class编译后将生成几个.class文件。
格式:
    [访问修饰符]  class   类名
    {
           0~N个成员变量
           0~N个方法
    }
【内部类】
(1)内部类:声明在类内部的类,称为内部类。
(2)内部类的特点:
    可以使用public、省略、protected、private等各种不同访问修饰符修饰;
    内部类编译以后,依然是独立的.class文件。文件名是“外部类名$内部名.class”,因此,自定义类名时,一般不使用$。
(3)内部类可以访问外部类的属性和方法,如果没有重名,可以直接访问;
    如果与内部类已有属性重名,可以使用“外部类.this.属性名”访问。
(4)外部类中,不能访问内部类的属性,public所修饰的也不行;
    如果需要访问,那么可以先实例化内部类,然后在使用内部类的属性
    In i = new In();i.test;
为什么使用内部类:
(1):增强封装,把内部类隐藏在外部类之内,不许其他类访问内部类。
(2):内部类能提高代码的可读性和可维护性,把小型类嵌入到外部类中结构上代码更靠近。
(3):内部类可以直接访问外部类的成员。
内部类根据使用不同的修饰符或者定位的位置不同,分成四张:
四种内部类:
① 实例内部类:  内部类没有使用static修饰.
② 静态内部类:  内部类使用了static修饰.
③ 局部内部类:  在方法中定义的内部类.
④ 匿名内部类适合于仅使用一次使用的类,属于局部内部类的特殊情况:
Java基础学习(三) -- OOP的三大特征、向上和向下转型、内部类之详解
(1)成员内部类,怎么实例化?
外部类名.内部类名 变量名=外部类对象.new 内部类名();
 class Person{
    class Test{
      }
   } Person.Test t = new Person().new Test();
Person p = new Person(); Person.Test t = p.new Test();
(2)内部类中访问外部类属性或方法?
外部类.this.属性名;
例如:Person.this.name;
 
(3)成员内部类声明的注意事项
   内部类不能与外部类重名;成员内部类中,不能出现静态属性,静态方法,静态内部类。但是,静态常量例外:public static final String name="1";
静态内部类
  (1)定义:使用static修饰的内部类,称为静态内部类。
  (2)实例化:外部类名.内部类名 变量 = new 外部类名.内部类名()
   class Person{
   public String name="1";
   public static int age=2;
   static class Test{
   }
}
Person.Test t=new Person.Test();
(3)静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,必须通过外部类的实例去访问
  即使用外部类名.属性名;
  Person.age;
(4)外部类不能访问静态内部类的非静态属性和方法;但可以访问静态内部类的静态属性和方法.
   即使用内部类名.属性名。
  Test.age;
静态内部类和成员内部类的区别
(1)声明方式和实例化方式不同:
   成员内部类实例化:Person.Test t=new Person().new Test();
   静态内部类实例化:Person.Test t=new Person.Test();
(2)成员内部类中,不能出现静态属性和方法,但静态内部类可以。
(3)外部类和内部类的互相访问权限不同。
局部内部类
(1)定义: 定义在某个类中的方法中的内部类。
(2)局部内部类是对外部完全隐藏的,只能在其作用域内被实例化。
(3)局部内部类可以访问外部类的属性和方法:写法: 外部类.this.属性名;
(4)局部内部类,不能访问其所在方法中的变量,只能访问常量,也就是final修饰的常量。
注意:局部内部类不能使用访问修饰符修饰。因为,它不属于类的成员,他属于方法中的局部变量。
匿名内部类
(1)写法:new Test1(){}
(2)含义:相当于一个匿名类,继承了Test1类,使用匿名内部类,将直接返回当前子类的对象
(3)Test1 t=new Test1(){};
  相当于:一个匿名内部类,继承了Test1类
   匿名内部类返回一个子类对象,并赋给了父类引用。
  因此,这一行代码相当于向上转型。
(4)匿名内部类通常用于直接实例化抽象类或接口.
   Test t=new Test(){
   //重写的抽象类Test1中的所有抽象方法.
  //相当于一个匿名内部类,继承test1类,然后返回这个匿名内部类的对象.
   }
上一篇:linux常用命令之tail


下一篇:unity UGUI动态字体显示模糊