一,对象的创建
对象就是类实例化的结果,要创建对象就要先有一个类,先创建一个狗类。
public class Dog {
// 约束了什么类型的属性
String color;
int age;
String name;
}
类创建完毕之后就可以创建对象了,和对对象内的属性进行复制操作了
// 创建对象
// 类名 变量名(对象名) = new 类名();
// 对象名.属性名 = 属性值;
public static void main(String[] args) {
// 创建对象
// 类名 变量名(对象名) = new 类名();
// 对象名.属性名 = 属性值;
Dog dog = new Dog();
dog.color = "黄色";
dog.name = "旺财";
dog.age = 12;
System.out.println(dog.color);
System.out.println(dog.age);
System.out.println(dog.name);
}
二,对象内部的细节
属性
在刚刚创建的狗的对象里面color,age,name叫做对象的属性,这里用了默认的修饰符。对于属性的修饰符有多种,修饰权限从小到大是 private,默认,protect,public。访问关系如下
方法
类(对象)中的方法分为多种,如果是使用private来修饰为了外部可以访问,就衍生了出了setter,getter方法,这二种方法,然后就是一些其他的方法,普通方法,构造器。方法和属性一样,同样可以被修饰符来做限制,限制外部是否可以访问我的方法,或者构造器,注意了因为 setter,getter方法是为了让外部可以访问的,所以一定是public修饰,在编译器里面一般用快捷键生成。构造器也是可以通过快捷键快速生成的。
package com.haogu.pojo;
public class Animal {
public String name;
public int age;
private String color;
//构造器重载
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
//构造器
public Animal() {
}
//普通方法
public void eat(){
System.out.println("动物" + this.name + "正在吃东西");
}
//一下全是set get方法
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 String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
这里面需要注意的是,构造器的构成 是必须 修饰符+方法名称(名称一定和类相同),普通方法是 修饰符+返回值+方法名
既然提到了重载就说明一下,重载和重写的区别,后续说到重写会再次说明的
重载: 发生在同一个类中,方法名必须相同,参数类型不同,个数不同,顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
重写: 发生在父子类中,方法名.参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。
构造器只能重载不能被重写
构造器的作用
有了构造器之后我们可以再创建对象的时候就对属性赋值,而不是需要使用,对象名称.属性的方式来赋值,注意传入的参数要和你构造的参数类型相对于
public static void main(String[] args) {
Animal animal = new Animal("老虎",18);
System.out.println(animal.name);
System.out.println(animal.age);
}
方法的调用
类名.方法名称
public static void main(String[] args) {
Animal animal = new Animal("老虎",18);
System.out.println(animal.name);
System.out.println(animal.age);
animal.eat();
}
三,对象的特点
1,封装
就是把对象的属性和行为(数据)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节,就是把不想告诉或者不该告诉别人的东西隐藏起来,把可以告诉别人的公开,别人只能用我提供的功能实现需求,而不知道是如何实现的。增加安全性。
我们创建的类就是封装,里面的属性和方法就是这个类的行为,拿上面例子来讲,我有一个动物类,动物都是有分类,年龄和行为的,我把他们写在一个类中就是封装,
2,继承
特点:单继承,一个类只能继承一个父类,一个父类可以有多个子类
子类继承父类的数据属性和行为,并能根据自己的需求扩展出新的行为,提 高了代码的复用性。
public class Cat extends Animal{
private String type;
@Override
public void eat(){
System.out.println("猫吃老鼠");
}
public void catchMouse(){
System.out.println( this.name + "抓老鼠");
}
}
我的例子里面继承了动物类,就代表我拥有动物类中的一切共有 属性和方法,并且我可以再他的基础上做出扩展,里面的type与抓老鼠方法就是做出的扩展,而eat方法是我对父类方法的重写。
重写只发生在父子类中,而重载只发生在一个类中
3,多态
指允许不同的对象对同一消息做出响应。即同一消息可以根据发送对象的不 同而采用多种不同的行为方式(发送消息就是函数调用)。封装和继承几乎都是为多态而准 备的,在执行期间判断引用对象的实际类型,根据其实际的类型调用其相应的方法。
个人认为多态最主要的体现就是,里氏代换原则(23中设计模式的设计原则),它强调子类应该能够替换掉它们的基类(父类),并且程序的行为不会改变。也就是说,任何使用基类(父类)对象的地方,都应该能够透明地使用其子类对象,而不会产生错误或不正确的行为。
四,关于对象特点的一些关键字
1.this和super的意义
this:当前对象
-
在构造器和非静态代码块中,表示正在new的对象
-
在实例方法中,表示调用当前方法的对象
super:引用父类声明的成员
无论是this和super都是和对象有关的。
2.this和super的使用格式
-
this
-
this.成员变量:表示当前对象的某个成员变量,而不是局部变量
-
this.成员方法:表示当前对象的某个成员方法,完全可以省略this.
-
this()或this(实参列表):调用另一个构造器协助当前对象的实例化,只能在构造器首行,只会找本类的构造器,找不到就报错
-
-
super
-
super.成员变量:表示当前对象的某个成员变量,该成员变量在父类中声明的
-
super.成员方法:表示当前对象的某个成员方法,该成员方法在父类中声明的
-
super()或super(实参列表):调用父类的构造器协助当前对象的实例化,只能在构造器首行,只会找直接父类的对应构造器,找不到就报错
-
3.避免子类和父类声明重名的成员变量
特别说明:应该避免子类声明和父类重名的成员变量
因为,子类会继承父类所有的成员变量,所以:
-
如果重名的成员变量表示相同的意义,就无需重复声明
-
如果重名的成员变量表示不同的意义,会引起歧义
在阿里的开发规范等文档中都做出明确说明
4.解决成员变量重名问题
-
如果实例变量与局部变量重名,可以在实例变量前面加this.进行区别
-
如果子类实例变量和父类实例变量重名,并且父类的该实例变量在子类仍然可见,在子类中要访问父类声明的实例变量需要在父类实例变量前加super.,否则默认访问的是子类自己声明的实例变量
-
如果父子类实例变量没有重名,只要权限修饰符允许,在子类中完全可以直接访问父类中声明的实例变量,也可以用this.实例访问,也可以用super.实例变量访问
class Father{
int a = 10;
int b = 11;
}
class Son extends Father{
int a = 20;
public void test(){
//子类与父类的属性同名,子类对象中就有两个a
System.out.println("子类的a:" + a);//20 先找局部变量找,没有再从本类成员变量找
System.out.println("子类的a:" + this.a);//20 先从本类成员变量找
System.out.println("父类的a:" + super.a);//10 直接从父类成员变量找
//子类与父类的属性不同名,是同一个b
System.out.println("b = " + b);//11 先找局部变量找,没有再从本类成员变量找,没有再从父类找
System.out.println("b = " + this.b);//11 先从本类成员变量找,没有再从父类找
System.out.println("b = " + super.b);//11 直接从父类局部变量找
}
public void method(int a, int b){
//子类与父类的属性同名,子类对象中就有两个成员变量a,此时方法中还有一个局部变量a
System.out.println("局部变量的a:" + a);//30 先找局部变量
System.out.println("子类的a:" + this.a);//20 先从本类成员变量找
System.out.println("父类的a:" + super.a);//10 直接从父类成员变量找
System.out.println("b = " + b);//13 先找局部变量
System.out.println("b = " + this.b);//11 先从本类成员变量找
System.out.println("b = " + super.b);//11 直接从父类局部变量找
}
}
class Test{
public static void main(String[] args){
Son son = new Son();
son.test();
son.method(30,13);
}
}
5,final关键字
修饰类:表示类不可被继承,修饰方法,表示方法不可被重写,修饰变量:变量一旦被复制就不能被修改了;