黑马程序员————JAVA基础之面向对象

              -----------android培训java培训、java学习型技术博客、期待与您交流!------------

对面向对象的理解:

     面向对象是一种编程思想,也是JAVA语言的一个重要特点,面向对象是相对于面向过程而言的。C语言就是一门面向过程的语言。它强调的是功能,而JAVA面向对象思想,是把功能封装到对象里面,强调的是对象。如把大象装到冰箱里面,对面向过程来说是:打开冰箱--->存储大象--->关闭冰箱。对面向对象来说就是冰箱打开--->冰箱存储---冰箱关闭。这时,程序员就从执行者变成了调用者。

类与对象的关系

现实生活中的对象:张三 李四。

JAVA通过对对象中共性内容进行抽取,通过类的形式进行体现。类是具体事物的抽象。具体对象就是对应java在堆内存中用new建立实体。

描述时张三、李四时:这些对象的共性有:姓名,年龄等属性,学习java功能。JAVA用类的方式来体现就是在描述对象的成员(成员属性,成员方法)。

属性:就是类中的成员变量。

行为:就是类中的成员函数。

对象:就是这类事物,实实在在存在个体。

例如:

class Student 
{
	private String name;
	private int age;
	private void study()
	{
		System.out.println("study java");
	}
}

以上的代码就定义了一个以学生为对象的类,这个对象具有姓名属性,年龄属性,还有一个学习Java的方法。如果要创建一个对象可以按照以下格式:Student  s=new Student();这样就创建了一个人的对象。

除此之外还可以定义匿名对象,如:new Student(); 匿名对象是对象的简化形式。

匿名对象的两种使用情况:

           1、当对对象方法仅进行一次调用的时。

            2、匿名对象可以作为实际参数进行传递。

 

成员变量和局部变量

作用范围:

  |--成员变量作用于整个类中。

  |--局部变量作用于函数中,或语句中。

在内存中的位置:

  |--成员变量在堆内存中,因为对象的存在,才在内存中存在。

  |--局部变量存在栈内存中。

构造函数:

对象一建立就会调用与之对应的构造函数。构造函数的作用:可以用于给对象进行初始化。

特点:

 1:函数名与类名相同;

 2:不用定义返回值类型;

 3:不可以写return语句。

构造函数的小细节:
当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。这个默认的构造函数权限和所属的类一致。如果类被public修饰,那么默认的构造函数也带public修饰符。如果累没有被public修饰,那么默认的构造函数也没有被public修饰。默认构造函数的权限是随着类的变化而变化的。

当在类中自定义了构造函数后,默认的构造函数就没有了。


构造函数和一般函数在写法上有不同。

在运行上也有不同。
构造函数是在对象一建立就运行。给对象初始化。
而一般方法是对象调用才执行,给是对象添加对象具备的功能。

一个对象建立,构造函数只运行一次。
而一般方法可以被该对象调用多次。

什么时候定义构造函数呢?
当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。

构造代码块:

 作用:给对象进行初始化。

 对象一建立就运行,而且优先于构造函数执行。


 和构造函数的区别:

 构造代码块是给所有对象进行统一初始化, 而构造函数是给对应的对象初始化。

 

 构造代码快中定义的是不同对象共性的初始化内容。

this关键字:

this:看上去,是用于区分局部变量和成员变量同名情况。

this到底代表的是什么呢?

this:就代表本类的对象,到底代表哪一个呢?

this代表它所在函数所属对象的引用。

简单说:哪个对象在调用this所在的函数,this就代表哪个对象。

this的应用:当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。

但凡本类功能内部使用了了本类对象,都用this表示。如以下代码:

class Person
{
	private String name;
	private int age;
	Person(int age)
	{
		this.age = age;
	}
	Person(String name)
	{
		this.name = name;
	}
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}

	public void speak()
	{
		System.out.println("name="+this.name+"...age="+this.age);
		this.show();
	}
	public void show()
	{
		System.out.println(this.name);
	}


	public boolean compare(Person p)
	{
		return this.age==p.age;

	}
}

class PersonDemo3 
{
	public static void main(String[] args) 
	{

		Person p1 = new Person(20);
		Person p2 = new Person(25);
		boolean b = p1.compare(p2);
		System.out.println(b);


	}
}

注意:this语句只能定义在构造函数的第一行,因为初始化要先执行。

 

static关键字:

静态:static。

用法:是一个修饰符,用于修饰成员(成员变量,成员函数).

当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用。类名.静态成员。

static特点:

1,随着类的加载而加载。也就是说:静态会随着类的消失而消失。说明它的生命周期最长。

2,优先于的对象存在;

明确一点:静态是先存在。对象是后存在的。

3,被所有对象所共享;

4,可以直接被类名所调用。

实例变量和类变量的区别:

1,存放位置。

 类变量(静态变量)随着类的加载而存在于方法区中。

 实例变量随着对象的建立而存在于堆内存中。

2,生命周期:

 类变量生命周期最长,随着类的消失而消失。

 实例变量生命周期随着对象的消失而消失。

3,主函数是静态的。

静态有利有弊

利处:对对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。 可以直接被类名调用。

弊端:生命周期过长。

          访问出现局限性。(静态虽好,只能访问静态。)

什么时候使用静态?

       从两方面下手: 因为静态修饰的内容有成员变量和函数。

1、什么时候定义静态变量(类变量)呢?

       当对象中出现共享数据时,该数据被静态所修饰。

       对象中的特有数据要定义成非静态存在于堆内存中。

2、什么时候定义静态函数呢?

       当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。

静态使用注意事项:

        1、静态方法只能访问静态成员。

             非静态方法既可以访问静态也可以访问非静态。

        2、静态方法中不可以定义thissuper关键字。

             因为静态优先于对象存在。所以静态方法中不可以出现this

静态代码块:

格式:

static

{

静态代码块中执行的语句;

}

特点:随着类的加载而执行,只执行一次,并优先于主函数。用于给类进行初始化的。

主函数(main)

public static void main(String[] args)

主函数:是一个特殊的函数。作为程序的入口,可以被jvm调用。

主函数的定义:

public:代表着该函数访问权限是最大的。

static:代表主函数随着类的加载就已经存在了。

void:主函数没有具体的返回值。

main:不是关键字,但是是一个特殊的单词,可以被jvm识别。

(String[] arr):函数的参数,参数类型是一个数组,该数组中的元素是字符串。字符串类型的数组。

主函数是固定格式的:jvm识别。jvm在调用主函数时,传入的是new String[0];
 

面向对象的三个特征:

         封装,继承,多态是面向对象的三个特征。

 

         封装: 是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

         封装的好处:1:将变化隔离;

                               2:便于使用;

                               3:提高重用性;

                               4:提高安全性。

          封装的原则:

             1:不需要对外提供的内容都隐藏起来。

            :2:属性都隐藏,提供公共方法对其访问。

 

          继承 

 

Java语言中:java只支持单继承,不支持多继承。

因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定运行哪一个。但是java保留这种机制,并用另一种体现形式来完成表示:多实现。

 java支持多层继承,也就是一个继承体系。但是如何使用一个继承体系中的功能呢 想要使用体系,先查阅体系中父类的描述。因为父类中定义的是该体系中的共性功能,通过了解共性功能,就可以知道该体系的基本功能,那么这个体系已经可以基本使用了。

那么在具体调用时,要创建最子类的对象,为什么?

一因为有可能父类不能创建对象;二是最子类实现的功能最多。

简单一句话:查阅父类功能,创建子类对象使用功能。

继承的好处:1:提高了代码的复用性;

                     2:让类与类之间产生了关系。有了这个关系,才有了多态的特性。

       注意:千万不要为了获取其他类的功能,简化代码而继承。

子父类出现后,类成员有哪些特点呢?

类中成员:1,变量。2,函数。3,构造函数。

1,变量
如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this;子类要访问父类中的同名变量,用super。

super的使用和this的使用几乎一致。this代表的是本类对象的引用。super代表的是父类对象的引用。

2,子父类中的函数。

子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。

这种情况是函数的另一个特性:重写(覆盖)

当子类继承父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新功能,而是使用覆盖特殊,保留父类的功能定义,并重写功能内容。

覆盖:

1,子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。

2,静态只能覆盖静态。

记住大家:

重载:只看同名函数的参数列表。

重写:子父类方法要一模一样。

3,子父类中的构造函数。

在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句 super();super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super()。

为什么子类一定要访问父类中的构造函数。

因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。

如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

注意:super语句一定定义在子类构造函数的第一行。

子类的实例化过程。

结论:

子类的所有的构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式super();当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。

多态

多态可以理解为事物存在的多种体现形态。

例:动物中猫,狗。猫这个对象对应的类型是猫类型,如:猫 x = new();同时猫也是动物中的一种,也可以把猫称为动物。动物  y = new();那么动物就是猫和狗具体事物中抽取出来的父类型。父类型引用指向了子类对象。

 

1,多态的体现
 父类的引用指向了自己的子类对象。
 父类的引用也可以接收自己的子类对象。
2,多态的前提
 必须是类与类之间有关系。要么继承,要么实现。
 通常还有一个前提:存在覆盖。

3,多态的好处
 多态的出现大大的提高程序的扩展性。

4,多态的弊端:
 提高了扩展性,但是只能使用父类的引用访问父类中的成员。

在多态中成员函数的特点:

在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。

在运行时期:参阅对象所属的类中是否有调用的方法。

简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。


在多态中,成员变量的特点:

无论编译和运行,都参考左边(引用型变量所属的类)。


在多态中,静态成员函数的特点:

无论编译和运行,都参考做左边。

interface Animal{  
02.    public abstract void eat();  
03.}  
04.  
05.class Cat implements Animal{  
06.    public void eat(){  
07.        System.out.println("吃鱼");  
08.    }  
09.    public void catchMouse(){  
10.        System.out.println("抓老鼠");  
11.    }  
12.}  
13.  
14.class Dog implements Animal{  
15.    public void eat(){  
16.        System.out.println("吃骨头");  
17.    }  
18.}  
19.  
20.public class DuoTai{ 
21.  
22.    public static void main(String[] args) {  
23.        // TODO Auto-generated method stub  
24.        Animal a = new Cat();   //类型提升,向上转型。  
25.        a.eat();  
26.          
27.        //如果想要调用猫的特有方法,如何操作?  
28.        //强制将父类的引用,转型成子类类型。向下转型。  
29.        Cat c = (Cat)a;  
30.        c.catchMouse();  
31.        //千万不要出现这样的操作,就是将父类对象转成子类类型。  
32.        //多态自始至终都是子类对象在做着变化。  
33.    }  
34.      
35.    public static void function(Animal a){  
36.        a.eat();  
37.        if(a instanceof Cat)    //类型判断  instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型)
38.        {  
39.            Cat c = (Cat)a;  
40.            c.catchMouse();  
41.        }  
42.    }  
43.  
44.}


         ---------android培训java培训、java学习型技术博客、期待与您交流!------------

 

 

 

 

 

 

 

 

 

 

 

 

 

 

                          


 

 


 


 

 

 

 

 

 

    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值