Day7Java
一、访问权限修饰符
1.public:公共权限 修饰类、属性、方法。可以在任意类种访问
2.protected:受保护的权限 修饰属性、方法。可以在同包类中访问,如果不是同包类,必须是该类的子类
3.default:同包权限 修饰类、属性、方法。只能在同包类访问
4.private:私有权限 修饰属性、方法。只能在本类中访问
public | protected | default | private | |
---|---|---|---|---|
同类 | √ | √ | √ | √ |
同包 | √ | √ | √ | |
不同包子类 | √ | √ | ||
不同包的其他类 | √ |
二、面向对象特征–封装
将类的某些信息隐藏,不允许外部程序直接访问,通过该类提供的方法堆隐藏信息访问和操作
好处:通过特定的方法访问,隐藏类信息,方便修改实现,方便加入控制语句
将属性私有化:
public class Demo{
private String name; //将类的成员变量访问权限设置为私有
public String getName (){//方法来获得私有值
return name;
}
public Demo(String name){//构造方法来赋值
this.name = name;
}
public void setName(String name){//方法来赋值
this.name=name;
}
//还可以加控制条件语句使得访问权限更小
public void setName(String name){
if(name.length>5){//控制语句
this.name=name;
}
}
}
将构造方法私有化:
static Myd myd=null;
private Myd(){//将构造方法私有化
}
//对外提供的获取唯一对象的公共方法
public static Myd getMyd(){//Myd是返回值类型
if(myd==null){//只能调一次,调一次后myd!=null
myd = new Myd();
}
return myd;
}
作用:只创建一个实例,比如任务管理器只能开一个
三、成员变量和局部变量
成员变量 | 局部变量 | |
---|---|---|
定义 | 类中 | 方法或方法的参数中 |
权限修饰符 | 可以用 | 不可用 |
初始化 | 非静态创建对象后,由构造方法初始化;静态随类加载时初始化 | 没有默认初始化值,必须自己赋值 |
生命周期 | 非静态随对象的创建而存在,随对象的销毁而消失;静态随类加载时而存在,随类卸载时消失 | 随方法的调用而存在,随方法的调用完毕而消失 |
内存中的位置 | 非静态与对象一起在堆中;静态与类信息存在方法区 | 与方法一起在栈中 |
四、继承
当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类,那么多个类中无需再定义这些属性和行为,只需要和这个大类构成继承关系就行
比如猫有名字,有年龄,可以吃东西,狗也是,就把名字,年龄,吃东西这两个属性一个行为定义到一个大类中,让猫类狗类继承这个大类
public class Animals{
public String name="123";
public int age;
public void eat(){
System.out.println("吃");
}
}
//子类:
public class Cat extends Animals{
public void catchMouse(){}//不是共有的
}
public class Dog extends Animals{
public void lookHome(){}//不是共有的
}
//运行
public static void main(String[] args){//子类可以用父类中的成员变量和方法
Cat cat=new Cat();
Dog dog=new dog();
String name1=cat.name;//123
String name2=Dog.name;//123
cat.eat();//吃
}
好处:
1.减少了代码冗余,提高了代码复用性
2.有利于功能的扩展
3.让类和类之间产生了is-a关系,为多态的使用提供了前提
is-a: 猫是动物 狗是动物
语法:
[修饰符] class 类B extends 类A{…}
B为子类/派生类,A为父类/基类
细节:
1.子类会继承父类所有的实例变量和实例方法
2.子类不能直接访问父类private的变量和方法
3.Java支持多层继承
4.Java只支持单继承,不支持多重继承(猫只能继承一个动物类,不能再继承生物类)
java.lang.Object是类层次结构的跟类,即所有类的父类,当没有显示继承其他类时,默认继承Object类
方法重写
当父类某个方法不是十分符合子类所需时,可以对此方法用相同的名字在子类中重新写一遍,在调用时会调用子类中的此方法,子类方法会覆盖父类方法
注意:构造方法和静态方法不能重写,成员变量不存在重写
public class Animals{
public String name;
public int age;
public void eat(){
System.out.println("吃");
}
}
//未重写
public class Dog extends Animals{
public void lookHome(){}
}
public static void main(String[] args){
Dog dog=new dog();
dog.eat();//吃
}
//方法重写
public class Dog extends Animals{
public void lookHome(){}
public void eat(){
System.out.println("重新吃");
}
}
public static void main(String[] args){
Dog dog=new dog();
dog.eat();//重新吃
}
方法重写规则:
1.子类重写方法必须和父类中被重写方法名称,参数列表相同
2.返回值一致
3.子类方法访问权限不能小于父类(父类私有方法不能重写,跨包的父类默认权限的方法也不能重写)
默认权限:包内部访问权限。即包内其他类可以访问该类,但是该类在包外部的其他类不能访问。
public class Animals {
void eat(){//默认权限
System.out.println("吃");
}
}
public class Dog extends Animals {//这是个跨包类继承
@Override//会报错,说明默认权限,包外类不能重写
public void eat(){
System.out.println("重新吃");
}
public static void main(String[] args) {
Dog dog=new Dog();
dog.eat();
}
}
4.子类方法抛出的异常不能大于父类被重写方法的异常
@Override使用说明:
@Override是java中的注解标签,用来标记,写在方法上,表示此方法是从父类中重写而来,用来检测是不是满足重写方法的要求,这个注解就算不写,只要格式满足要求,也是正确的方法覆盖重写。建议保留,这样编译器可以帮助我们检查格式,另外也可以让阅读源代码的程序员清晰的知道这是一个重写的方法。
super关键字:
super来调用父类中的指定操作:
super可以访问父类中定义的属性,成员方法,可以用于在子类构造器中调用父类的构造器
注意:
尤其当子父类出现同名成员,方法时,可以用super表明调用的是父类
super的追溯还可以是父类的父类
super代表父类的内存空间的标识,this标识本类对象的引用
public class Dog extends Animals{
public void eat(){
super.eat();//super引用父类方法
System.out.println("重新吃");
}
}
public static void main(String[] args){
Dog dog=new dog();
dog.eat();//吃 重新吃
}
误区:不要误把super以为是父类对象,在创建子类对象时,不会创建父类对象,只会把父类中的信息加载到子类对象中储存
继承中的构造方法:
子类不会继承父类的构造方法,只能通过super(形参)来调用父类指定的构造方法
规定super(形参),必须声明在构造器的首行
如果在子类构造器的首行没有显示调用super(形参),则子类此构造器默认调用super(),即调用父类中空惨的构造器
这么做是为了保证先对父类成员初始化
父类:
public class Animals {
public String name;
public Animals(String name3){
this.name=name3+"动物";
System.out.println(this.name);
}
}
子类:
public class Dog extends Animals {
String name;
public Dog(String name2){
super(name2);
this.name=name2+"狗";
}
运行:
public static void main(String[] args) {
Animals animals=new Animals("100");//100动物
System.out.println(animals.name);//100动物
Dog dog=new Dog("旺旺");//旺旺动物
System.out.println(dog.name);//旺旺狗
System.out.println(animals.name);//100动物
}
//animals.name和dog里面的super.name没有关系,说明super不是父类对象