Java面向对象基本特征

简介:

1、封装性

    一个对象和外界的联系应当通过一个统一的接口,应当公开的公开,应当隐藏的隐藏。

    属性的封装:Java中类的属性的访问权限的默认值是default,要想隐藏该属性或方法,就可以加private(私有)修饰符,来限制只能够在类的内部进行访问。对于类中的私有属性,要对其给出一对方法(getXxx(),setXxx())访问私有属性,保证对私有属性的操作的安全性。 

    方法的封装:对于方法的封装,该公开的公开,该隐藏的隐藏。方法公开的是方法的声明(定义),即(只须知道参数和返回值就可以调用该方法),隐藏方法的实现会使实现的改变对架构的影响最小化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public  class  TestDemo {
     public  static  void  main(String[] args) {
         Person person= new  Person();
         person.tell();
         person.setAge(- 20 );
         person.setName( "张三" );
         person.tell();
     }
}
class  Person{
     private  int  age;
     private  String name;
     public  int  getAge() {
         return  age;
     }
     public  void  setAge( int  age) {
         if (age> 0 &&age< 150 ){
             this .age = age;
         }
     }
     public  String getName() {
         return  name;
     }
     public  void  setName(String name) {
         this .name = name;
     }
     void  tell(){
         System.out.println( "姓名:" +name+ ";年龄:" +age);
     }
}

备注:

(1)Java匿名对象:只需要使用一次的场所。例如:new Person().tell();

      

(2)Java构造方法:构造方法名称必须与类名一致,没有返回指,可以重载,主要为类中的属性初始化。

      

(3)值传递的数据类型:八种基本数据类型和String(String也是传递的地址,只是String对象和其他对象是不同的,String是final的,所以String对象值是不能被改变的,值改变就会产生新对象。那么StringBuffer就可以了,但只是改变其内容,不能改变外部变量所指向的内存地址)。

引用传递的数据类型:除String以外的所有复合数据类型,包括数组、类和接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public  class  TestRef4 {
public  static  void  main(String args[])
   {
     int  val= 10 ;;
     StringBuffer str1, str2;    
     str1 =  new  StringBuffer( "apples" );
     str2 =  new  StringBuffer( "pears" );
     
     System.out.println( "val:"  + val);
     System.out.println( "str1 is "  + str1);
     System.out.println( "str2 is "  + str2); 
     System.out.println( "..............................." );
     
     modify(val, str1, str2);  
     System.out.println( "val is "  + val);
     System.out.println( "str1 is "  + str1);
     System.out.println( "str2 is "  + str2);
   }
  
   public  static  void  modify( int  a, StringBuffer r1,StringBuffer r2)
   {      
       a =  0 ;
       r1 =  null ;        
       r2.append( " taste good" );
       System.out.println( "a is "  + a);
       System.out.println( "r1 is "  + r1);
       System.out.println( "r2 is "  + r2);
       System.out.println( "..............................." );
   }
}

输出结果为:

1
2
3
4
5
6
7
8
9
10
11
val: 10
str1 is apples
str2 is pears
...............................
a is  0
r1 is  null
r2 is pears taste good
...............................
val is  10
str1 is apples
str2 is pears taste good

(4)this关键字:表示类中的属性或方法;调用类中的构造方法,例如:this();表示当前对象。


(5)static关键字:static申明属性为全局属性;static申明方法直接通过类名调用;使用static方法时,只能访问static申明的属性和方法,而非static申明的属性和方法时不能访问。



2、继承性

    在程序中,使用extends关键字让一个类继承另一个类,继承的类为子类,被继承的类为父类,子类会自动继承父类所有的方法和属性

    class 子类 extends 父类{}

示例1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public  class  ExtendsDemo1 {
     public  static  void  main(String[] args) {
         Student student= new  Student();
         student.setAge( 15 );
         student.setName( "张三" );
         student.setScore( 90 );
         student.tell();
         System.out.println( ".............................." );
         System.out.println( "name:" +student.getName()+ ";age:" +student.getAge()+ ";score:" +student.getScore());
     }
}
 
class  Person{
     private  int  age;
     private  String name;
     public  int  getAge() {
         return  age;
     }
     public  void  setAge( int  age) {
         this .age = age;
     }
     public  String getName() {
         return  name;
     }
     public  void  setName(String name) {
         this .name = name;
     }
}
 
class  Student  extends  Person{
     //private int age;
     //private String name;
         private  int  score;
       //public int getAge() {
     //return age;
     //}
     //public void setAge(int age) {
     //this.age = age;
     //}
     //public String getName() {
     //return name;
     //}
     //public void setName(String name) {
     //this.name = name;
         //}
     public  int  getScore() {
         return  score;
     }
     public  void  setScore( int  score) {
         this .score = score;
     }
     public  void  tell(){
         System.out.println( "name:" +getName()+ ";age:" +getAge()+ ";score:" +getScore());
     }
}

输出结果:

name:张三;age:15;score:90

..............................

name:张三;age:15;score:90


2.1 在Java中只允许单继承(一个子类只允许有一个父类),子类不能直接访问父类的私有成员

示例2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public  class  ExtendsDemo2 {
  public  static  void  main(String[] args){
  PetWorker petWorker= new  PetWorker();
  petWorker.setAge( 20 );
  petWorker.setWork( "teacher" );
  petWorker.tell();
  }
}
/**
  * 创建类People
  * @author Admin
  *
  */
class  People{
     private  int  age;
     public  int  getAge() {
         return  age;
     }
     public  void  setAge( int  age) {
         this .age = age;
     }
}
/**
  * 创建Worker类,单继承People类
  * @author Admin
  *
  */
class  Worker  extends  People{
     private  String work;
     public  String getWork() {
         return  work;
     }
     public  void  setWork(String work) {
         this .work = work;
     }
}
/**
  * 创建PetWorker类,单继承Worker类
  * @author Admin
  *
  */
class  PetWorker  extends  Worker{
     public  void  tell() {
         System.out.println( "age:" +getAge()+ ";work:" +getWork());
     }
}

输出结果:

age:20;work:teacher


2.2 Java方法重写

   定义:方法名称相同,返回值类型相同,参数也相同,其实质就是子类定义了和父类同名的方法。

   重写限制:被子类重写的方法不能拥有比父类方法更严格的访问权限,private<default<public

   子类调用父类中的方法:super.方法名(参数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public  class  ExtendsDemo1 {
     public  static  void  main(String[] args) {    
     B b= new  B();
     b.tell();
     }
}
 
class  A{
     public  void  tell(){
        System.out.println( "父类中的tell方法" );
     }
}
 
class  extends  A{
     public  void  tell() {
     super .tell();
     System.out.println( "我重写了tell方法" );
     }
     void  say(){
     super .tell();
     }
}

输出结果:

   父类中的tell方法

   我重写了tell方法

   父类中的tell方法

方法重载与方法重写区别

方法重载(Overloading)
方法重写(Override)
定义 方法名称相同,参数的类型或个数不同
方法名称、参数类型、返回值类型全部相同
权限要求 对权限没有要求 被重写的方法不能拥有比父类更加严格的权限
范围 发生在一个类中 发生在继承中


2.3 抽象类与接口

  final能申明类、方法和属性,使用final申明的类不能被继承,使用final申明的方法不能被重写,使用final申明的变量变成常量(定义时要赋值),常量是不可以修改的。

  抽象类:包含一个抽象方法的类就是抽象类。

定义:

abstract  class ClassName{

    属性

    方法

    抽象方法

}

(1)抽象方法:申明而未实现的方法,抽象方法必须使用abstract关键字申明,只有方法名和参数,没有方法体。

(2)抽象类被子类继承,子类(若不是抽象类)必须重写抽象类中的所有抽象方法。

(3)抽象类不能实例化,要通过其子类进行实例化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public  class  AbstractClassDemo1 {
     public  static  void  main(String[] args) {
         StuClass stuClass= new  StuClass();
         stuClass.tell();
         stuClass.say();
     }
}
 
abstract  class  AbsClass{
     int  age;
     public  void  tell(){
         System.out.println( "父类中的tell方法" );
     }
     public  abstract  void  say();
}
 
class  StuClass  extends  AbsClass{
     @Override
     public  void  say() {
         System.out.println( "子类实现父类抽象类中的say抽象方法" );
     }
}


  接口可以理解为一种特殊的类(没有构造方法),里面全部是由全局常量和公共的抽象方法组成,接口的实现必须通过子类,使用关键字implements,而且子类可以多实现接口。一个接口不能实现(implements)另一个接口,但它可以继承多个其它的接口。接口定义如下:

[修饰符] interface 接口名 [extends 父接口名列表]{

    [public] [static] [final] 全局常量;

    [public] [abstract] 抽象方法;

}

样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public  abstract  class  InterfaceDemo1 {
     public  static  void  main( String [] args) {
         InterfaceClass interfaceClass= new  InterfaceClass();
         interfaceClass.print( 1 .0f);
     }
}
 
class  InterfaceClass  implements  CalInterface1,CalInterface2{
     @Override
     public  void  print(float r) {
         System.out.println( "半径为" +r+ "的圆面积:" +getArea(r)+ ",周长:" +getCircumference(r));
     }
     @Override
     public  float getArea(float r) {
         float area=PI*r*r;
      return  area;
     }
     @Override
     public  float getCircumference(float r) {
         float circumference= 2 *PI*r;  
      return  circumference; 
     }
}
//定义接口CalInterface1
interface  CalInterface1 
{
     float PI= 3 .14159f; //PI默认为public static final类型
     float getArea(float r); //方法getArea()默认为public abstract类型,注意抽象方法没有方法体 
     public  abstract float getCircumference(float r); //计算面积
}
//定义接口CalInterface2
interface  CalInterface2
{    
     void  print(float r); //打印输出结果
}
//定义接口CalInterface3,继承接口CalInterface1和CalInterface2
interface  CalInterface3  extends  CalInterface1,CalInterface2{
     
}


输出结果:

    半径为1.0的圆面积:3.14159,周长:6.28318


抽象类和接口的对比

参数
抽象类 接口
实现 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 子类使用关键字implements来实现接口。
构造器 可以有构造器 无构造器
修饰符 抽象方法可以有public、protected和default这些修饰符 接口方法默认修饰符是public。你不可以使用其它修饰符。
main方法 抽象方法可以有main方法并且我们可以运行它 没有main方法
多继承 抽象类可以继承一个类和实现多个接口 接口只可以继承一个或多个其它接口
速度 要快些 慢些

(1)如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类。

(2)如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。

(3)如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。


3、多态性

    定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。

    多态性的体现:方法的重载和重写;对象的多态性。

    多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。

    对象的多态性:

        向上转型:程序会自动完成

            父类 父类对象=子类实例

        向下转型:强制类型转换

            子类 子类对象=(子类)父类实例

    instanceof关键字:用于判断一个引用类型变量所指向的对象是否是一个类(或接口、抽象类、父类)的实例。


示例1:基于继承实现的多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public  class  DuoTaiDemo {
     public static void main(String[] args) {
         function(new Cat());
         function(new Dog());
         System.out.println( "................................." );
         / /  向上转型
         Animal a  =  new Cat();
         a.eat();
         / /  向下转型
         Cat c  =  (Cat) a;
         c.catchMouse();
     }
 
     public static void function(Animal a) {
         a.eat();
         / /  用于子类型有限
         / /  或判断所属类型进而使用其特有方法
         if  (a instanceof Cat) {
             Cat c  =  (Cat) a;
             c.catchMouse();
        
         else  if  (a instanceof Dog) {
             Dog c  =  (Dog) a;
             c.kanJia();
         }
     }
}
 
abstract  class  Animal {
     abstract void eat();
}
 
class  Cat extends Animal {
     @Override
     void eat() {
         System.out.println( "吃鱼" );
     }
     void catchMouse() {
         System.out.println( "抓老鼠" );
     }
}
 
class  Dog extends Animal {
     @Override
     void eat() {
         System.out.println( "啃骨头" );
     }
     void kanJia() {
         System.out.println( "看家" );
     }
}

输出结果:

    吃鱼

    抓老鼠

    啃骨头

    看家

    .................................

    吃鱼

    抓老鼠


示例2:基于继承实现的多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public  class  DuoTaiDemo1 {
     public static void main(String[] args) {
         A a1  =  new A();
         A a2  =  new B();
         B b  =  new B();
         C c  =  new C();
         D d  =  new D();        
         System.out.println( "1--"  +  a1.show(b));
         System.out.println( "2--"  +  a1.show(c));
         System.out.println( "3--"  +  a1.show(d));
         System.out.println( "4--"  +  a2.show(b));
         System.out.println( "5--"  +  a2.show(c));
         System.out.println( "6--"  +  a2.show(d));
         System.out.println( "7--"  +  b.show(b));
         System.out.println( "8--"  +  b.show(c));
         System.out.println( "9--"  +  b.show(d));
     }
}
 
class  A {
     public String show(D obj) {
         return  ( "A and D" );
     }
     public String show(A obj) {
         return  ( "A and A" );
    
}
class  B extends A{
     public String show(B obj){
         return  ( "B and B" );
     }
     
     public String show(A obj){
         return  ( "B and A" );
    
}
class  C extends B{
}
class  D extends B{
}

输出结果:

    1--A and A

    2--A and A

    3--A and D

    4--B and A

    5--B and A

    6--A and D

    7--B and B

    8--B and B

    9--A and D

结果分析:

    当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级由高到低依次为为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

wKiom1VRzIDyzyrhAABGie-tZLQ746.jpg


示例3:基于接口实现的多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public  class  DuoTaiDemo2 {
     public static void main(String[] args) {
         work(new USBDisk());
         work(new Printer());
     }
     public static void work(USB u) {
         u.start();
         System.out.println( "正在进行中..." );
         u.stop();
     }
}
 
interface USB{
     void start();
     void stop();
}
 
class  USBDisk implements USB{
     @Override
     public void start() {
         System.out.println( "U盘开始工作" );
     }
     @Override
     public void stop() {
         System.out.println( "U盘停止工作" );
     }
}
 
class  Printer implements USB{
     @Override
     public void start() {
         System.out.println( "打印机开始工作" );
     }
     @Override
     public void stop() {
         System.out.println( "打印机停止工作" );
     }
}

输出结果:

    U盘开始工作

    正在进行中...

    U盘停止工作

    打印机开始工作

    正在进行中...

    打印机停止工作

    备注:父类对象会调用子类对象重写后的方法。








     本文转自stock0991 51CTO博客,原文链接:http://blog.51cto.com/qing0991/1639375,如需转载请自行联系原作者









相关文章
|
1天前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
7 2
|
2月前
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
26天前
|
SQL 安全 Java
JAVA代码审计SAST工具使用与漏洞特征
JAVA代码审计SAST工具使用与漏洞特征
25 2
|
2月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
30 4
|
2月前
|
SQL 安全 Java
JAVA代码审计SAST工具使用与漏洞特征
JAVA代码审计SAST工具使用与漏洞特征
47 1
|
2月前
|
Java
接口和抽象类【Java面向对象知识回顾②】
本文讨论了Java中抽象类和接口的概念与区别。抽象类是不能被实例化的类,可以包含抽象和非抽象方法,常用作其他类的基类。接口是一种纯抽象类型,只包含抽象方法和常量,不能被实例化,且实现接口的类必须实现接口中定义的所有方法。文章还比较了抽象类和接口在实现方式、方法类型、成员变量、构造方法和访问修饰符等方面的不同,并探讨了它们的使用场景。
接口和抽象类【Java面向对象知识回顾②】
|
19天前
|
存储 Java 程序员
Java基础-面向对象
Java基础-面向对象
11 0
|
2月前
|
安全 Java Go
面向对象程序设计语言:Java
Java语言语法和C语言和C++语言很接近,很容易学习和使用,Java丢弃了C++中很少使用的、很难理解的、令人迷惑的特性,Java语言不使用指针,而是引用,并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧
51 2
|
3月前
|
Java 数据处理 开发者
【Java基础面试十二】、说一说你对面向对象的理解
这篇文章阐述了面向对象是一种以类和对象为基础,通过封装、继承和多态等概念来模拟现实世界中的事物及其相互关系的程序设计方法,它强调以事物为中心进行思考和系统构造,与结构化程序设计相比,更符合人类的自然思维方式。
【Java基础面试十二】、说一说你对面向对象的理解
|
3月前
|
Java
【Java基础面试十三】、面向对象的三大特征是什么?
这篇文章介绍了面向对象程序设计的三大基本特征:封装、继承和多态,其中封装隐藏对象实现细节,继承实现软件复用,多态允许子类对象表现出不同的行为特征。
【Java基础面试十三】、面向对象的三大特征是什么?