一封装
1封装性:插线板,使用者只需要知道插上插座电器可以工作即可,至于内部线路如何连接,不需要了解
2.什么是封装::在类中,对于不想被类外直接访问的成员,进行私有化,同时对外提供一个共有的方法为了访问私有的成员
3.private:使用private访问权限实现成员的私有化,private修饰的成员就是私有成员,只能在类内部直接访问,类外不能直接访问
4.get和set方法
get方法表示访问私有属性的方法:
语法:
public 属性类型 getXx(){ return 属性; }
set方法表示修改私有属性的值的方法:
public void setXx(参数类型 参数){ this.xx = 参数; }
二:static 关键字
static关键字只能修饰类成员。
静态代码块
代码块:单独存在的一对大括号中的代码称为代码块。代码块分为:静态代码块,动态代码块,局部代码块
局部代码块:声明在方法中的代码块,执行时机与声明位置相关(在方法中按顺序从上到下执行)。
写在方法里的代码块(不管是静态方法还是非静态方法,代码块都是顺序执行)
动态代码块:又称构造代码块,声明在类体中的代码块,创建对象时自动执行一次,每创建一个对象就执行一次动态代码块【早于构造函数】。
静态代码块:使用static关键字修饰的动态代码块,在类加载时自动执行,并只执行一次。
静态属性:
成员变量=全局变量=非静态变量
静态方法想调用非静态方法:创建对象,用对象调用
执行顺序:
1按顺序执行该类的静态代码块或静态成员
2顺序执行main()方法体,当出现new 该类()时,顺序执行非静态数据成员或非静态块(因为这些东西是每个对象一份的,在创建对象时被开辟空间)
3执行该类的构造方法
注:1不管静态方法还是非静态方法如果不在main()中调用是不会自动执行的
2非静态块和非静态是数据成员可以看成是是等价的,静态块和静态是数据成员可以看成是是等价的
静态的数据成员在共享区内独立于对象(所以用对象.调用没有意义,但可以这样使用),属于类,可以用类名.调用,静态变量也称类变量。
静态属性先于对象,不依赖于对象,可以直接通过类名直接访问。
静态方法
先于对象的方法,不依赖于对象,可以直接通过类名直接调用
Java中非静态方法是否共用同一块内存?
注:答案是对的公用一块内存。
但是对于每一个对象在调用该非静态方法时,会把this传给这个方法(原理同python方法调用),所产生的数据是这个对象私有的,并能保存起来。详细请看:
https://blog.csdn.net/lulongzhou_llz/article/details/7465661
MyObject obj=null; //内存还没有创建
MyObject obj1=""; //开辟了内存空间,但里面什么也没有
三继承
1.继承的概念:在原有类的基础上,产生一个新的类,在新的类中可以访问原有类中的非私有成员,并且可以添加一些自己独有的成员,这个过程叫做继承2
不能被子类继承的成员:
私有成员:私有成员不能被子类继承
构造方法:父类中的构造方法不能被子类继承,但是会在子类的构造方法中调用(子类的构造方法中默认第一条语句是调用父类的构造方法)
2继承的特点:
1)类单继承,一个子类只能有一个父类
2)一个父类可以有多个子类
3)子类只能继承父类中非私有的成员
4)父类的引用可以指向子类的实例,但是,父类的引用无法访问子类中独有的成员
四super关键字(用法和this类似)
super表示父类的引用
1)super.属性:表示访问父类中的属性,当子类中定义了与父类同名的属性时,若想在子类中访问父类的同名属性,需要使用super.属性访问
2)super.方法:表示调用父类中的方法,在子类中需要调用父类中没有被重写的方法时,需要使用super.方法调用
3)super():表示调用父类的构造方法,注意:super()必须是子类构造方法中第一条语句子类中构造方法默认第一条语句会调用父类的无参数构造方法super(),也可以手动调用父类中带参数的构造方法
问题:
代码块自动初始化构造方法之类的顺序不明
public class Animal{
int a = 10;
public String name;
public int age;
public Animal(){}
public Animal(String name, int age){
this.name = name;
this.age = age;
}
public void fun(){
System.out.println("Animal类的fun方法");
}
}
public class Dog extends Animal{
int a = 20;
public Dog(){
super();//调用父类的构造方法
}
@Override
public void fun(){
System.out.println(a);//输出结果为20
System.out.println(super.a);//输出结果为10
super.fun();//调用父类中没有被重写过的方法
}
}
继承中的构造方法:父类中的构造方法不会被子类继承,但是创建子类对象时,会调用父类的构造方法。也就是说,创建子类对象时,需要先创建一个父类的对象,在父类对象实例的内存的基础上附加一块子类独有成员的内存整体是一个子类对象。
五方法重写
1什么是方法的重写:在继承过程中,子类中从父类继承来的方法无法满足自己的需求时,可以在子类中对方法进行完善,这 个过程叫做方法重写,方法的重写相当于在子类中覆盖父类中的方法。
2方法重写的要求
从方法的签名部分入手
访问权限 其他修饰符 返回值 方法名(参数列表)
重写方法的过程中,子类中的方法访问权限,大于等于父类中被重写方法
其他修饰,相对随意
返回值类型,相同 方法名必须完全一致 参数列表完全相同
3法的重写和方法的重载的区别
方法的重载:Overload,在同一个类中一组方法名形同,参数个数或类型不同的方法,互为重载方法
方法的重写:Override,在继承过程中,在类中完善父类中继承来的方法
方法重写是:@Override注解表示验证重写方法的格式是否正确
4有关方法重写之后的调用:
只要在子类中重写过的方法,创建出的对象只要有关子类都会执行重写后的方法
也就是说对象在调用方法时,实例决定执行的方法,与引用无关
六访问权限
例子
package day3_1;
public class Person{
public String name;
protected int age;
char sex;
private String school;
public Person(String name,int age,char sex,String school)
{
this.name=name;
this.age=age;
this.sex=sex;
this.school=school;
}
public Person(){}
public static void main(String[] args)
{
Person p=new Person("程新",1,'m',"哈尔滨佛学院");
System.out.println(p.name);
System.out.println(p.age);
System.out.println(p.sex);
System.out.println(p.school);//可以在该类中用该类的对象访问其私有成员
}
}
package day3_1;
public class Student extends Person{
public static void main(String[] args) {
Student p=new Student();
System.out.println(p.name);
System.out.println(p.age);
System.out.println(p.sex);
//System.out.println(p.school);同包子类不可访问父类私有成员
}
}
package day3_1;
public class Demo {
public static void main(String[] args) {
Person p=new Person();
System.out.println(p.name);
System.out.println(p.age);
System.out.println(p.sex);
//System.out.println(p.school);同包中的类不可访问别的类的私有成员
}
}
package day7;
import day3_1.Person;
public class Student extends Person{
public static void main(String[] args) {
Student s=new Student();
System.out.println(s.name);
System.out.println(s.age);//不同包的子类可以访问父类的保护成员
//System.out.println(s.sex);
//System.out.println(s.school);
}
}
package day7;
import day3_1.Person;
public class Demo {
public static void main(String[] args) {
Person p=new Person();
System.out.println(p.name);
//System.out.println(p.age);报错
//System.out.println(p.sex);报错
//System.out.println(p.school);报错
}
}
构造方法可以被public protected default private修饰:
public class Father {
public int a;
public int b;
public int c;
public Father()
{
}
protected Father(int a)
{
this.a=a;
}
Father(int a,int b)
{
this.a=a;
this.b=b;
}
private Father(int a,int b,int c)
{
this.a=a;
this.b=b;
this.c=c;
}
public static void main(String[] args) {
Father pu=new Father();
System.out.println(pu.a+" "+pu.b+" "+pu.c );
Father pro=new Father(1);
System.out.println(pro.a+" "+pro.b+" "+pro.c );
Father de=new Father(1,2);
System.out.println(de.a+" "+de.b+" "+de.c );
Father pri=new Father(1,2,3);
System.out.println(pri.a+" "+pri.b+" "+pri.c );
}
}
输出:
0 0 0
1 0 0
1 2 0
1 2 3
七杂项
1类中变量要定义为私有的,写公有的get(),set()函数
eclipse自动生成get(),set()函数:右键->Source->Getters and Setters
2;表示一行代码的结束,所以;和;;;;;;没有区别
3父类子类有同名参数不同的方法,子类继承该父类方法,又有自己的同名方法(相当于方法重载)
4子类继承父类公有、保护、默认成员(指变量和方法):如果子类在同包下,子类对象可直接调用这些成员,如果子类在不同包中,子类对象不能调用默认成员。如果子类在同包下,子类中的父类对象可以直接调用该父类本身的这些成员,如果子类在不同包中,子类中父类对象不能调用父类自己的默认成员。
5权限从大到小:public protected default(不写修饰符) private
6在继承关系中:
子类继承父类的非私有成员变量或方法
子类中方法名如果和父类方法名一致,参数不同,也是方法的重载overload
子类中方法名如果和父类方法名一致,参数表相同,权限大于等于父类权限,叫方法重写override
7.在调用子类构造方法时:
new 子类会先调用父类的构造方法再调用子类的构造方法:SubClass sub=new SubClass();它会先执行父类的构造方法(在子类构造方法第一行自动调用),如果没显示的调用父类的构造方法,系统会自动调用父类的默认构造方法,在显示调用父类狗仔方法时,可以任意形式的父类构造方法,但只能显示调用一次,且必须写在子类有效代码的第一行。接着执行子类的构造方法。因为先创建了父类对象再创建子类对象,所以子类包含父类,所以可以用自己给父类赋值。
8.方法的重写:子类重写(覆盖)父类中的方法:作用范围和父类相同或比父类大(有点要发扬光大),注:异常范围和父类相同或比赋了小(缺点要尽量避免)
9将子类实例赋给父类引用时,如果父类中没有该子类的方法就调不到。
10父类可以强制类型转换赋值给子类,但一使用就会报错。
11类中方法(包括构造方法)和数据成员的修饰符:public protected default(啥也不写) private,类的修饰符只能是public或不写
12单例设计模式:
//设计模式:解决某一类问题最有效的方式
//单例设计模式:解决的是一个类只有一个对象的问题
//1:构造函数私有化
//2:在类中创建自身类型的对象
//3:把对象提供出去,通过定义一个public的静态函数返回该对象
class SingleInstance{
private SingleInstance(){}
static private SingleInstance s;
static public SingleInstance getInstance() {
if(s==null)
s=new SingleInstance();
return s;
}
}
public class TestA {
public static void main(String[] args) {
SingleInstance s1=SingleInstance.getInstance();
SingleInstance s2=SingleInstance.getInstance();
System.out.println(s1==s2);
}
}
输出:true